CAM智能化助力PCB智能制造
文章目录
前言
古语云:路漫漫其修远兮,吾将上下而求索!
- 二十一世纪二十年代了,科技发展日新月异,所有的事物都在快速发展,人类的文明也得到了极大的繁荣,唯一不变的是美帝国主义亡我之心不死,作为红旗下茁壮成长的我终于不再是早上八九点钟的太阳,我现在至少是中午的太阳.我有一个梦想,我希望世界和平,梦想太大风浪大,我没出过海经不起什么大风大浪,这个梦想我肯定实现不了,人贵要有自知之明,踏着梦想砥砺前行我肯定说得到,做不做得到我不知道,但是我坚信还是要先做,怕死不死不成立,我们追求稳步前进但是一定心怀远大梦想,梦想一定是我们前进道路的方向,失去梦想的人注定只能行尸走肉.
正所谓敢想敢干,说干就干.首先,我介绍一下我自己,本人生于红旗下,成长于天地间,自呱呱坠地就使得我家倾家荡产,没有错,我就是计划生育的非计划人口,30年前的国家负担,30年后生育的主力,生我嫌多,我生嫌少,我的成长过程自然而又充满变革,时代的红利都完美的避开,我就是悲催的80后,成长在大变革大发展的30年,如今新的30年已经重新开启,我们的国家已经走完由穷到富的历史征程,接下来将进入由富到强新的发展阶段,新的变革潮流已经形成,墨守成规者必定会在新潮流新趋势下被淘汰,敢于革新者必将成为下一阶段的领头羊,各行各业无所不一,做为一名合格的搬砖人员或者行业沙子能拿3K还是30K每月考验的不光是你的智慧,更是眼界与胆识.
PCB制造业在国内已经取得长足的进步及发展,随着产品种类的丰富多样及生产工艺能力的不断提升,对工程前端生产指示及工具设计都提出了更高的要求,如何提高效率,品质将是制前工程永恒的课题,作为PCB制前工程自动化资深从业人员,我无时无刻不在思考这个课题,以我之浅见,完成课题核心在于“解放思想,开拓眼界,大胆实施,强力执行”!解放何种思想?1.效率不够人来凑,人手不够加班凑;2.改变工程部门在工厂处于辅助部门的认知,改变系统开发人员在工程处于辅助人员甚至服务员的认知;以我为主,坚持系统化,自动化,智能化!
一、系统化
1.定义
- 将工作分割细化,以点带面,使复杂的笼统的工作分割为有组织有结构的具体的工作细则,简而言之,化繁为简,以量变产生质变,以质变产出奇效.
2.思考
-
如何系统化?
答:首先将工作按职责划分并分类,然后将分类后的工作分割成单元模块,再次将单元模块具体操作步骤化,最后将每步执行脚本化. -
能否详细说明?
答:举例说明,CAM自动化系统,单凭字面仅能泛化理解,并不能直观的感受及认识什么是自动化系统,接下来用思维导图的方式给大家展示:

- 如上图所示,我们看到的所有模块汇总就叫CAM自动化系统,样例中又包含三大子系统或者子模块,子系统又包含更小的颗粒系统或者模块,以此不停的细化分割直至到最小的分支或者颗粒,如果以人为例,我们就可以称之为"人类生物系统",所以CAM自动化系统并不是简单的脚本程式汇总,而是一个相对庞大的需要统一协调的达成一至执行的框架性执行合集,从来就不是所谓"系统人员"一个人的事,而是一整个部门甚至全公司更甚至全行业同行的事情,我们将这个系统分拆组合,细化分类的整个过程就做系统化,系统化是自动化实施的基石,没有经过系统化的自动化我们称之为形式自动化,并不能真正解决根本问题,没有有效组织及规范要求的自动化程式,功能再强大也仅仅只是功能强大,就如一堆无组织无纪律的散兵游勇,再勇敢也只是散兵游勇,并不能发挥出团队合作的效能.
3.方法
- 学会使用工具,使用何种工具?
首先人与动物最大的区别在于人会使用工具及易于沟通交流,21世纪的工具是相当丰富的,掌握更多的资源及工具就能掌握先机,就能实现利益最大化,所有人在社会的阶层地位都是由个人掌握的资源和能力来决定的,我们说的能力就是对各类工具的使用能力及与任何对象的沟通能力,任何一种能力都能使我们获取更多的资源,所以任何时候都要对自己的能力有清晰的认知.
综上所述,我们在工作中学会使用各类工具,掌握更多工具使用技巧,学会沟通交流就会让你在同行中抢得先机.
回到正题,我们在系统化的过程中使用何种工具,本人极力推荐思维导图软件XMind,
这是一款功能强大且易掌握使用的多平台国产软件,当然还有许多类似的功能软件大家可以自行搜索选择合适自己的即可.
下面我们看看用思维导图软件整理后的CAM系统人员工作及管理事项,会不会将我们的思维具象化,让所有人都能懂你在做什么,你要做什么,你要怎么做.
- 以上我们讲到了思维导图工具的使用及思维具象化的方法,接下来我们学习使用工具将我们要做的事情变成有组织有结构有计划的可执行的任务(维护计划和项目开发计划),使用企业微信的公司我强烈推荐直接在企业微信中搞定一切,没有企业微信也不用慌,我们可以使用WPS,方法是一样的,企业微信集成了我们制作项目的所需的一切软件功能,如思维导图,流程图,excel,工作群组搭建,线上会议及任务追踪等.
- 如下图,我们制作一个需求的处理的周工作任务计划,任务计划包含了周制作项目及时间计划,同时我们还可以添加所有需要关注周计划的相关人员,真正做到信息实时共享,进度全盘掌握.

二、标准化
1.人员的标准化管理
-
团队的搭建及分工
工程 PIE 开发 维护 提出,测试,执行需求 整理规范及标准 方案制定,项目开发及文档编写 项目维护升级及培训 -
建立项目开发标准流程图

-
1.3.团队的管理
自动化的实施分为开发和维护两个过程,团队的建立并不是传统的某个专门部门,一般实施会建立项目部门,这样做的好处在于,统一协调,统一行动,让各职能部门真正发挥各自领域的专业性,团队核心能力说明:- (1).工程部门熟悉运作流程及制作要求,部分优秀人员的操作经验就是良好的自动化实施基础,但是并不是所有的人员能力及经验都是全面的,均衡的,工程负责人也并不是全能,建立项目组的目的就是让优秀的人员及良好的经验都能参与到实施的过程中来,让优秀的个人经验变成优秀的团队经验,既能提升团队协作能力,也能让的用户全程参与实施,做一名参与者而不是机械的执行人员或者旁观者,总而言之就是充分挖掘工程人员的潜力及充分利用良好的经验;
- (2).PIE部门作为成本管控及标准制定的担当可以为团队的标准化管理及规范管理提供专业的助力,从体系端规范自动化实施的管理标准,让一切项目的执行都是有据可查,有规可依,避免项目制作规则混乱及不成文靠嘴上说的问题出现;
- (3).软件部开发组,作为实际的实施部门,根据需求及规则制定详细的实施及开发计划,让所有的需求及规范都能变为实际可操作的程式代码,这个过程控制一般会要求制定专业的项目制作甘特图,以便大家都是能实时的掌控项目的进度;
- (4).软件部维护组,任何项目的开发完结并不能代表整个项目的完结,所有的需求及规则都是动态的,需要专业的系统维护人员根据需求部门的反馈,及时完善,优化及导入新的规则.
- 综上所述,自动化项目的实施都会分为两个阶段,开发阶段及维护阶段,项目的团队管理并不是以固定部门职责来定义,而是以项目负责人为核心来管理运行,如何选定项目负责人自然是以对项目的理解,掌控及实施能力来定义,这样能有效避免一言堂及屁股指挥大脑的情况发生.
-
1.4.系统人员的培训(以Centos7/InCAMPro/Python3/PyQt5环境为主)
专业的人做专业的事,专业的人员培养必不可少,任何时候掌握人才培养的能力永远比找寻人才更能抢占先机,培训课程及计划必须安排上:前章.专业人员培训
人员培训课程表
章节 课程 小节 关键点 课时 第一章.Linux系统学习 第1课.系统安装 1.虚拟机安装(Windows) 掌握虚拟机基本配置 60min 2.Centos7系统镜像下载 安装分区只做引导分区,内存交换分区,根分区 60min 第2课.系统配置 1.网络配置 了解网络配置 10min 2.SMB共享服务配置 掌握SMB服务配置 10min 3.NFS共享服务配置 掌握NFS服务配置 10min 4.VNCSERVER服务配置 掌握vncservers服务配置 30min 5.自动任务配置 掌握crontab配置及原理 30min 第3课.常用命令 1.Centos7常用终端指令 cd,df,ps,ls,ln,su,cp,mv,scp,ssh,rm,touch,mkdir 60min 第4课.vim编辑器 1.vim基础操作 掌握vim基本操作 30min 第二章.开发环境配置 第5课.安装Anaconda3(Python3) 1.Anaconda安装 了解为什么选择Anaconda 30min 2.Python3环境配置 不能覆盖系统原有Python环境,会影响系统 10min 第6课.常用的Python模块安装 1.PyQt5图像界面模块安装 conda安装和pip安装 10min 2.pymysql/pymssql数据库操作模块安装 掌握常用数据库操作模块的安装 10min 3.xlrd/xlwt库安装 掌握常用excel处理模块的安装 10min 4.其他常用库安装 掌握常用处理模块的安装 10min 第7课.安装集成开发工具(PyCharm) 1.PyCharm安装 掌握集成开发软件的安装配置 10min 2.PyCharm常规设置 一些常用的插件及AI插件,集成环境的配置 20min 3.PyCharm配置 Python环境虚拟环境及本地环境 10min 4.PyCharm下安装Python第三方模块 掌握集成开发环境下常用模块的安装方法 10min 第8课.安装数据库(MySQL/SQLServer) 1.安装CentOS时自动安装装MySQL数据库服务 掌握系统安装时的一些必要服务同步安装 10min 2.MySQL数据库服务常规安装配置 掌握Linux下的MySQL数据库安装 20min 3.SqlServer数据库服务安装配置 掌握Windows下Sql Server数据库的安装 20min 第9课.安装navicat(数据库操作客户端) 1.数据库操作客户端navicat安装 掌握数据库客户端软件navict的安装及激活 10min 2.navicat配置数据库连接 掌握客户端连接数据库的基本操作 10min 3.navicat常规操作 掌握通过客户端对数据库的查改增删基本操作 10min 第10课.CAM软件脚本语言环境配置 1.解释型语言脚本运行配置文件讲解 掌握奥宝CAM软件脚本运行机制 10min 2.编译型型语言脚本运行配置文件讲解 / 10min 第11课.Git安装配置 1.下载安装Git程序 了解git的作用,掌握基本的代码托管操作 10min 2.配置Git用户信息 / 10min 3.上传并提交代码(gitee代码托管平台) / 10min 4.下载托管的代码(gitee代码托管平台) / 10min 第12课.Svn安装配置 1.下载安装Svn程序 了解Svn的作用,掌握基本的代码托管操作 10min 2.配置Svn用户信息 / 10min 3.上传并提交代码(本地服务器) / 10min 4.下载托管的代码(本地服务器) / 10min 第三章.工程软件学习 第13课.Genesis2000/InCAM/InCAMPro安装配置 1.Genesis2000安装(Windows) 理解各个模块的基本功能和配置方法 10min 2.Genesis2000安装(CentOS) 掌握Linux下genesis服务配置 30min 3.InCAM/InCAMPro安装(CentOS) 掌握Linux下incam服务配置及License配置 30min 4.CAM软件服务端配置 理解服务端与客户端的异同 30min 第14课.Genesis2000/InCAM/InCAMPro操作基础 1.操作界面及功能模块介绍 了解软件基本操作(功能模块对照) 10min 2.基本操作演示 掌握最基本的操作功能 30min 3.进阶操作演示 掌握一些技巧性的操作 30min 第15课.Genesis2000/InCAM/InCAMPro系统参数 1.系统参数设置 掌握系统常规参数设置 15min 2.自定义功能及界面设置 掌握快捷键及自定义功能的添加设置 15min 3.软件Library管理及配置 掌握系统常规参数设置 15min 4.系统管理员模块配置 掌握系统管理员模块参数设置 15min 第16课.Genesis2000/InCAM/InCAMPro基础命令 1.常用LMC的录制 掌握原始代码基本获取方式及转化方式 30min 2.完整的LMC参数查询 掌握完整原始代码获取方式及查询官方文档 10min 3.LMC及Line_Hooks防呆指令 掌握软件防呆设计原理及使用时机 20min 第四章.系统维护学习 第17课.Linux系统常见异常问题汇总 1.操作系统相关 掌握常规的系统维护事项 10min 2.CAM软件 掌握CAM软件常用的维护事项 20min 3.系统磁盘空间容量异常 掌握磁盘空间自动监控及管理方法 30min 第五章.脚本开发学习 第18课.Python3基础 1.Python3环境搭建 掌握Python3语言环境的搭建 10min 2.PyCharm开发环境配置 掌握Python3开发环境的搭建 10min 3.Python3基础语法 掌握Python3基础语法 30min 4.Python3数据类型 理解字符串,数值,元组,列表,集合,字典类型 20min 5.Python3数据类型转换 掌握数据类型之间的相互转换方法 10min 6.Python3注释 掌握Python3的注解方式并灵活应用 10min 7.Python3运算符 掌握Python3的常用运算符 10min 8.Python3条件控制 掌握Python3的条件控制语句 10min 9.Python3循环语句 掌握Python3的循环控制语句 10min 10.Python3推导式 理解并能灵活应用推导式 10min 11.Python3函数 理解函数的基本结构 10min 12.Python lambda(匿名函数) 理解lambda函数并掌握一些常见的应用场景 10min 13.Python3数据结构 理解Python3数据结构的基本操作 10min 14.Python3模块 掌握模块的导入及基本调用方法 10min 15.Python3输入和输出 掌握常用的格式化方法(%, ‘{0}’.fomat(a)等) 10min 16.Python3文本处理 掌握文本处理的基本操作及异常处理 10min 17.Python3模块之OS(文件/目录方法) 掌握最常用的OS模块基本操作 10min 18.Python3错误和异常 掌握程式异常处理机制 10min 第19课.Python3进阶 1.Python3面向对象 理解面向对象思想及面向对象编程的好处 20min 2.Python3命名空间和作用域 了解Python3关键字,掌握命名规则及作用域 10min 3.Python3标准库 了解Python3标准库及熟练使用常见标准库 10min 4.Python3实例 掌握Python3编程基本技能 30min 5.Python测验检验 Python3编程基本技能水平 30min 第20课.Python3高阶 1.Python3正则表达式 掌握常用的正则表达式写法基本检验方法 30min 2.Python数据库连接驱动之MySQL 掌握Pyhton3对MySQL数据库的驱动及操作 20min 3.Python数据库连接驱动之Sql Server 掌握Pyhton3对Sql Server数据库的驱动及操作 10min 4.Python3邮件发送之SMTP 掌握Pyhton3自动发送邮件的处理方式 30min 5.Python3多线程 掌握Pyhton3多线程编程 10min 6.Python3数据解析之XML 掌握Pyhton3对XML的解析 10min 7.Python3数据解析之JSON 掌握Pyhton3对JSON的解析 10min 8.Python3日期和时间处理 掌握Pyhton3对日期及时间的处理 10min 9.Python3内置函数 了解Python3常用内置函数 10min 10.Python3模块安装工具之pip 掌握pip工具的操作 10min 11.Python3模块之urllib 了解Python3网页URL操作及网页内容处理 30min 12.Python3模块之operator 了解operator模块基本应用场景 10min 13.Python3模块之math 了解math模块基本数学运算函数 10min 14.Python3模块之requests 掌握requests模块调用WebApi 10min 15.Python3模块之random 理解模块主要用于生成随机数 10min 16.Python3模块之PyQt5 掌握模块并能灵活的开发出各种交互界面 60min 17.Python3模块之pymysql/pymssql 掌握模块并能轻松的通过模块操作数据库 30min 第21课.Python3编程实战开发(CAM脚本开发) 1.自定义基础接口包IncamClasses.py 理解Python3连接CAM软件的基础命令模块 30min 2.自定义基础接口包InfoClasses.py 掌握模块基本结构及扩展方法,灵活应用与开发 30min 3.自定义基础接口包LcmClasses.py 掌握模块基本结构及扩展方法,灵活应用与开发 30min 4.自定义基础接口包MainClasses.py 掌握模块基本结构及扩展方法,灵活应用与开发 10min 5.自定义基础接口包JobClasses.py 掌握模块基本结构及扩展方法,灵活应用与开发 30min 6.自定义基础接口包sendMail.py 掌握模块基本结构及扩展方法,灵活应用与开发 30min 7.自定义基础接口包GuiClasses.py 掌握模块基本结构及扩展方法,灵活应用与开发 30min 8.自定义基础接口包SqlClasses.py 掌握模块基本结构及扩展方法,灵活应用与开发 30min 9.自定义基础接口包TextClasses.py 掌握模块基本结构及扩展方法,灵活应用与开发 30min 10.自定义基础接口包FileClasses.py 掌握模块基本结构及扩展方法,灵活应用与开发 30min 11.自定义基础接口包gatewayClasses.py 理解模块与IncamClasses.py的异同 10min 12.牛刀小试(切换InCAMPro系统单位) 掌握基本的脚本开发能力 10min 13.往前一步(自动添加Pad脚本) 进一步掌握脚本开发能力 10min 14.加快脚步(有交互的添加Pad脚本) 掌握基本的交互界面脚本开发能力 10min 15.奔跑向前(自动交互的添加Pad脚本) 掌握基本的自动界面交互脚本开发能力 30min 16.破风而行(模块化的系统开发) 掌握脚本开发能力的同时掌握脚本的扩展能力 10min 17.顺势而上(面向AI编程) 了解新的科技所带来的效率提升 20min 第22课.Python3编程实战开发(Line_Hooks开发) 1.如何用Python3来开发Line_Hooks脚本 理解奥宝CAM软件的脚本运行机制及防呆机制 10min 2.实战操作(新建料号防呆脚本开发) 掌握前置,后置防呆脚本的开发 20min 3.实战操作(用户操作记录) 理解奥宝CAM软件的保存机制及日志存储方式 20min 4.实战操作(建立料号履历) 理解软件机制,利用Line_Hooks做一些灵活操作 30min 5.实战操作(让用户无法犯错) 掌握主动防呆,过程防呆,替用户把住易错点 30min 6.实战操作(让用户无感操作) 掌握主动防呆,过程防呆,替用户做一些常用操作 30min 7.实战操作(让用户只做该做的事) 掌握主动防呆,过程防呆,替用户规划好操作权限 30min 第23课.Python3编程实战开发(脚本全自动执行) 1.奥宝CAM软件的无界面模式 了解奥宝CAM软件无界面模式及常用场景 10min 2.实战操作(无界面输出tgz资料) 掌握常用的无界面执行指令及脚本开发 30min 3.实战操作(无人值守输出tgz资料) 掌握无人值守脚本的开发及应用 30min 第24课.Python3编程实战开发(外挂脚本执行) 1.奥宝CAM软件的gateway执行模式 了解奥宝CAM软件gateway指令及常用场景 30min 2.实战操作(通过外挂管理料号库) 掌握通过外挂执行CAM脚本指令 30min 3.实战操作(通过外挂实现camguide) 深入理解并充分利用gateway模式开发脚本 60min 第六章.项目开发学习 第25课.快板系统项目详解 1.项目建立及需求分析 了解项目的概念及如何做需求分析 20min 2.项目小组建立及任务分解 了解项目成员划分及任务分解规则 20min 3.项目计划制作及执行 掌握项目计划甘特图及项目推进进度追踪方法 20min 4.了解项目整体架构及编程思想 / 10min 5.外挂主体程式讲解 掌握主体程式开发及功能架构 10min 6.外挂功能模块组成 掌握功能模块开发方法 10min 7.外挂的扩展及维护 掌握扩展方法及功能模块维护方法 10min 8.一切皆可外挂 理解集成化界面带来的效率提升核心点 10min 第一章.Linux系统学习
第1课.系统安装
第1节.虚拟机安装(Windows)
-
步骤1.VMware Workstation Pro下载: 下载地址
-
步骤2.安装虚拟机软件(安装演示):
注意事项:
1.虚拟机硬件配置不能超过本机实际硬件配置;
2.根据实际的需求选择硬件配置;
3.新建虚拟机时可以先不装载ISO文件,待完成所有配置后在执行加载系统ISO文件安装.课后作业:
- 下载VMware WorkStation Pro安装包。
- 运行VMware WorkStation Pro安装包。
- 安装VMware WorkStation Pro。
- 输入许可证密钥(如果有)。
- 完成安装并启动VMware WorkStation Pro。
- 配置网络和虚拟机设置。
- 开始使用VMware WorkStation Pro。
第2节.Centos7系统镜像下载安装
-
步骤1.CentOS7系统ISO镜像下载: 网易163镜像源下载地址
-
步骤2.虚拟机安装CentOS7系统镜像(安装演示):
- (1).选择配置好的虚拟机并添加下载好的操作系统镜像:
- (2).启动虚拟机并安装CentOS7镜像文件:
- (3).安装完成后进入CentOS 7系统的图形界面,默认使用kde桌面模式:
注意事项:
1.分区选择手动新建分区,只分(boot分区,内存交换swap分区及"/"根分区);
2.安装时选择"带GUI的服务器"模式并且直接勾选全部服务模块安装;
3.在安装过程中配置好普通用户及网络服务课后作业:
- 下载CentOS 7系统ISO镜像安装包。
- 安装CentOS 7系统ISO镜像。
- 在安装过程中按要求完成系统配置。
- 完成安装CentOS 7系统ISO镜像后进入KDE桌面。
- (1).选择配置好的虚拟机并添加下载好的操作系统镜像:
第2课.系统配置
第1节.网络配置
网络配置参考: 超详细CentOS7 NAT模式(有图形化界面)网络配置
-
步骤1.查看网络状态
首先,我们需要查看当前 CentOS 系统的网络状态。我们可以通过运行以下命令来检查网络状态:ip addr show该命令会列出所有网络接口及其配置信息。我们可以看到每个接口的 IP 地址、MAC 地址和状态等信息。如果系统上有多个网络接口,则需要查看每个接口的状态和配置。
-
步骤2.配置网络接口
如果您需要手动配置网络接口,则可以编辑 /etc/sysconfig/network-scripts/ifcfg- 文件。该文件包含系统的网络配置信息。其中 是网络接口的名称,例如 eth0。
例如,如果您要配置 eth0 接口,可以使用以下命令编辑 /etc/sysconfig/network-scripts/ifcfg-eth0 文件:sudo nano /etc/sysconfig/network-scripts/ifcfg-eth0在该文件中,您可以设置 IP 地址、子网掩码、网关和 DNS 等信息。以下是一个样例配置文件:
DEVICE=eth0 TYPE=Ethernet ONBOOT=yes BOOTPROTO=static IPADDR=192.168.1.100 NETMASK=255.255.255.0 GATEWAY=192.168.1.1 DNS1=8.8.8.8 DNS2=8.8.4.4在该配置文件中,
DEVICE 表示网络接口的名称,
ONBOOT 设置为 yes 表示开机自动启用该接口,
BOOTPROTO 设置为 static 表示手动配置 IP 地址,
IPADDR 表示 IP 地址,
NETMASK 表示子网掩码,
GATEWAY 表示默认网关,
DNS1 和 DNS2 表示 DNS 服务器地址。
可以根据需要修改这些值。 -
步骤3. 重启网络服务
完成配置后,您需要重启网络服务以使更改生效。可以使用以下命令重启网络服务:sudo systemctl restart network该命令将会将新的配置文件写入系统,并重启网络服务以使更改生效。
-
步骤4. 检查网络连接
完成配置和重启后,您应该能够使用 ping 命令检查网络连接。例如,您可以使用以下命令 ping 网关 IP 地址:ping 192.168.1.1如果 ping 命令能够成功响应,则表示网络连接正常。
注意事项:
1.设置静态IP地址时确保IP没有被分配;
2.网络设置时IPv6默认设置为忽略;
3.IPv4设置网络默认设置为静态IP,具体的配置参数需由IT提供.课后作业:
- 完成通过终端操作配置好CentOS7网络。
- 完成通过操作界面配置好CentOS7网络。
第2节.SMB共享服务配置
-
步骤1.使用root权限登录到CentOS 7服务器:


在普通用户终端输入"su"后回车; 输入root密码后回车切换到root用户 -
步骤2.使用root权限登录到CentOS 7服务器安装共享服务:
使用命令yum install samba -y安装Samba软件包。yum -y install samba结果截图如下:

-
步骤3.在Samba配置文件中定义共享目录:
- (1).打开文件/etc/samba/smb.conf并添加以下行:
其中,[share]为共享名称,comment为共享描述,path为共享目录的路径,browseable表示是否可浏览,writable表示是否可写入,guest ok表示是否允许匿名用户访问。vim /etc/samba/smb.conf [centos7] comment = Centos7 DVD directory. path = /media public = yes read only = yes - (2).输入上述内容,定义一个新的只读共享centos7:
设置物理目录为 /mediamkdir /media mkdir /media/cdrom/ mount /dev/cdrom /media/cdrom/
- (1).打开文件/etc/samba/smb.conf并添加以下行:
-
步骤4.挂载光盘到/meda/cdrom,以方便用户远程访问:
使用命令systemctl start smb启动Samba服务,并使用systemctl enable smb设置开机自启。systemctl start smb (启动共享) testparm (确认参数没问题)完成上述结果截图如下:

-
步骤5.以账号(用户)访问共享:
- (1).设置账号:
其中,vina是你自己定义的Samba用户名。你会被要求输入密码。useradd vina pdbedit -a –u vina (密码) (再输入密码)
结果截图如下:

- (2).设置安全访问:
(防火墙配置:如果启用了防火墙,需要开放Samba服务的相关端口,包括TCP端口139和445,以及UDP端口137和138)
结果截图如下:systemctl stop firewalld setenforce 0 sestatus -b | grep samba (用命令可了解当前安全访问状态)

- (3).测试访问:在另一台Windows客户端电脑上,使用Windows资源管理器访问该共享目录,输入Samba用户账号和密码,即可访问共享目录。
在客户机访问共享打开一个窗口
在地址栏输入\192.168. 168.129 (这里为自己虚拟机IP地址)
在登录窗口输入用户名:vina(这里也为你自己设置的用户名,不可用中文),输入密码。
打开光碟的共享名,看到文件后结果截图如下:
课后作业:
- 下载并安装samba服务
- 配置SMB服务并成功共享Linux系统目录到本机
- (1).设置账号:
第3节.NFS共享服务配置
- NFS共享服务配置:详细参考链接
- NFS 网络文件系统,是一种使用于分布式文件系统的协议,功能是通过网络让不同的机器,不同的操作系统能够彼此分享各自的数据,让应用程序在客户端通过网络访问位于服务器磁盘中的数据,是在类Unix系统间实现磁盘文件共享的一种方法。
- NFS服务器可以允许NFS客户端将远端NFS服务器端的共享目录挂载到本地的NFS客户端中,在本地的NFS客户端的机器看来,NFS服务器端共享的目录就好像自己的磁盘分区和目录一样。
- NFS服务器是通过读取/etc/exports配置文件设定那个客户端可以访问那些NFS共享文件系统,如下我们提供了NFS的基本配置写法。
[共享目录] [允许谁来访问][权限] [可用主机名][权限] [其他主机权限] /nfs 192.168.1.1(rw) localhost(rw) *(ro,sync) /nfs 192.168.1.0/24(rw) localhost(rw) *(ro,sync) /nfs 192.168.1.1(rw) 192.168.1.2(ro) 192.168.1.3(ro,sync) - 步骤1.NFS服务端配置
-
(1).在配置NFS共享文件之前,我们先来放行NFS的几个常用服务,并将防火墙默认设置为拒绝状态.
[root@localhost ~]# firewall-cmd --add-service=nfs [root@localhost ~]# firewall-cmd --add-service=mountd [root@localhost ~]# firewall-cmd --add-service=rpc-bind [root@localhost ~]# firewall-cmd --add-service=nfs --permanent [root@localhost ~]# firewall-cmd --add-service=mountd --permanent [root@localhost ~]# firewall-cmd --add-service=rpc-bind --permanent -
(2).通过YUM仓库快速安装NFS相关的软件包.
[root@localhost ~]# yum install -y rpcbind nfs-utils* Package rpcbind-0.2.0-47.el7.x86_64 already installed and latest version Package 1:nfs-utils-1.3.0-0.61.el7.x86_64 already installed and latest version Nothing to do -
(3).创建需要共享的文件,并拷贝相关的文件内容,并设置SeLinux规则.
[root@localhost ~]# mkdir -p /public [root@localhost ~]# chmod o+rw /public/ [root@localhost ~]# chcon -R -t public_content_t /public/ -
(4).修改NFS主配置文件,并写入要访问的主机列表.
[root@localhost ~]# vim /etc/exports /public 192.168.1.0/24(rw,sync) #[共享目录] [允许谁来访问][权限] [可用主机名][权限] [其他主机权限] #/nfs 192.168.1.1(rw) localhost(rw) *(ro,sync) #/nfs 192.168.1.0/24(rw) localhost(rw) *(ro,sync) -
(5).重启NFS服务,和守护进程,并设置开机自启动.
[root@localhost ~]# systemctl restart nfs [root@localhost ~]# systemctl restart rpcbind [root@localhost ~]# systemctl enable nfs [root@localhost ~]# systemctl enable rpcbind [root@localhost ~]# systemctl restart nfs-server [root@localhost ~]# systemctl enable nfs-server
-
- 步骤2.NFS客户端配置
-
(1).通过YUM仓库快速安装NFS相关的软件包.
[root@localhost ~]# yum install -y rpcbind nfs-utils* Package rpcbind-0.2.0-47.el7.x86_64 already installed and latest version Package 1:nfs-utils-1.3.0-0.61.el7.x86_64 already installed and latest version Nothing to do -
(2).创建挂载点,并设置SeLinux规则.
[root@localhost ~]# mkdir -p /mnt/nfsmount [root@localhost ~]# chcon -R -t public_content_t /mnt/nfsmount -
(3).手动挂载目录,可通过mount命令来实现,并将配置文件写入到开机自启动列表.
# mount -t nfs -o 选项 服务主机:/服务器共享目录 /本地挂载没记录 [root@localhost ~]# mount -t nfs -o rw,sync 192.168.1.5:/public /mnt/nfsmount [root@localhost ~]# df -hT |grep "public" Filesystem Type Size Used Avail Use% Mounted on 192.168.1.5:/public nfs4 17G 1.9G 16G 12% /mnt/nfsmount [root@localhost ~]# vim /etc/fstab 192.168.1.1:/public /mnt/nfsmount nfs default 0 0 -
(4).NFS提供了查看NFS共享状态的一系列命令.
[root@localhost ~]# nfsstat #显示服务端与客户端状态 [root@localhost ~]# nfsstat -s #只显示服务端状态 [root@localhost ~]# nfsstat -c #只显示客户端状态 [root@localhost ~]# nfsstat -n #仅显示NFS与RPC信息 [root@localhost ~]# nfsstat -m #显示挂载信息 [root@localhost ~]# nfsstat -l #以列表信息显示信息 [root@localhost ~]# rpcinfo -m 127.0.0.1 #显示指定主机rpcbind操作列表 [root@localhost ~]# rpcinfo -p 127.0.0.1 #显示指定主机RPC注册信息 [root@localhost ~]# rpcinfo -s #显示所有RPC注册信息 [root@localhost ~]# showmount -e 127.0.0.1 #显示服务器可用资源 [root@localhost ~]# showmount -a 127.0.0.1 #查看所有客户链接信息 [root@localhost ~]# showmount -d 127.0.0.1 #只显示客户输出信息 [root@localhost ~]# exportfs -a #全部挂载或卸载配置文件中的内容 [root@localhost ~]# exportfs -r #重新加载配置文件中的信息 [root@localhost ~]# exportfs -u #停止单一目录的共享 [root@localhost ~]# exportfs -au #停止所有服务端的共享 [root@localhost ~]# exportfs -ra #重新共享所有目录
- 下载并安装NFS服务
- 配置NFS服务并成功共享Linux系统目录
-
第4节.VNCSERVER服务配置
-
步骤1.VNC 简介
VNC(Virtual Network Computing) 是使用网络建立连接的一个虚拟桌面,用来远程操作计算机的一种技术,日常会有很多中场景需要远程来控制和操作服务器等计算机。 -
步骤2. CentOS 安装 VNC Server
在root用户下使用 yum 安装 tigervnc-server。# yum install tigervnc-server看到“完毕”则表示安装成功!
-
步骤3. 配置 VNC Server
拷贝一份 VNC 配置文件模板到如下目录。# cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:1.service-
(1). 指定用户
CentOS 7 需要编辑配置文件,修改 user 关键字为实际用户名;其它版本不需要进行该步骤。# sudo vim /etc/systemd/system/vncserver@:1.service
[例]:这里笔者的用户名为 imaginemiracle,该位置修改为对应的用户名即可。 -
(2). 启动对应配置文件的服务
重新加载系统服务# systemctl daemon-reload开启该服务
# systemctl start vncserver@:1开启自启动该服务
# systemctl enable vncserver@:1
-
-
步骤4. 开启 VNC Server
切换到对应用户# su imaginemiracle执行 vncpasswd 配置 VNC 连接密码,这里不设置仅查看模式的密码,因为一般用不到仅查看的方式。

执行如下命令启动对应的 VNC Server$ vncserver :1注意:后面的 id 号即表示哪个桌面 id,其使用的端口号为 5900+id,如此处使用的端口号则为 5901,若使用防火墙则需要开放该端口,才可以连接。

-
步骤5. 连接使用
-
(1).新建连接

-
(2).这里在 VNC Server 处填写 IP:ID,Name 处随意写。

注意:这里笔者使用的是之前的配置,若按照本文配置来,则这里的 id 需要改为 1。
-
(3).配置完成后,双击连接,若出现如下弹窗则说明 VNC Server 启动成功,其后面的 590X 表示该服务所使用的端口号。(5900 + ID)

-
(4).点击继续并输入密码即可进入远程虚拟桌面

OK,连接成功!

日常处理:
1.如何规避vnc密码限制必须6位字符及客户端免密登录vnc?
答:进入用户终端,输入"vncpasswd -f 你的密码或者空字符 > /home/username/.vnc/passwd"后回车两次
2.批量终止vnc窗口服务?
答:进入用户终端,输入"pkill Xvnc"或者"pkill vncserver"
$ vncpasswd -f incam > /home/incam/.vnc/passwd
$ pkill Xvnc课后作业:
- 下载并安装VNCSERVER服务
- 配置VNCSERVER服务并成功共享Linux系统桌面
-
第5节.自动任务配置
-
在 centos7上使用crontab定时任务,自动定时执行脚本
添加/编辑 Crontabcrontab -e crontab [-u username] -e 默认情况下,系统会编辑当前用户的crontab命令集合查看Crontab
crontab -l crontab [-u username] -l删除Crontab
crontab -r crontab [-u username] -r 慎用。可以直接crontab -e 进行编辑载入
crontab [-u user] file 将file做为crontab的任务列表文件并载入crontab 如果在命令行中没有指定这个文件,crontab命令将接受标准输入(键盘)上键入的命令,并将它们载入crontab。配置路径
/var/spool/cron/root (以用户命名的文件) 是所有默认存放定时任务的文件 /etc/cron.deny 该文件中所列出用户不允许使用crontab命令 /etc/cron.allow 该文件中所列出用户允许使用crontab命令,且优先级高于/etc/cron.deny/var/log/cron 该文件存放cron服务的日志示例
每五分钟执行 */5 * * * * 每105分钟执行一次 */105 * * * * 每小时执行 0 * * * * 每天执行 0 0 * * * 每周执行 0 0 * * 0 每月执行 0 0 1 * * 每年执行 0 0 1 1 * 1.每天 02:00 执行任务 0 2 * * * /bin/sh backup.sh 2.每天 5:00和17:00执行任务 0 5,17 * * * sh /a.sh 3.每分钟执行一次任务 * * * * * sh /a.sh 4.每周日 17:00 执行任务 0 17 * * sun sh /a.sh 5.每 10min 执行一次任务 */10 * * * * sh /a.sh 6.在特定的某几个月执行任务 * * * jan,may,aug * /script/script.sh 7.在特定的某几天执行任务 0 17 * * sun,fri /script/scripy.sh 在每周五、周日的17点执行任务 8.在某个月的第一个周日执行任务 0 2 * * sun [ $(date +%d) -le 07 ] && /script/script.sh 9.每四个小时执行一个任务 0 */4 * * * sh /a.sh 10.每周一、周日执行任务 0 4,17 * * sun,mon sh /a.sh 11.每30秒执行一次任务 * * * * * sh /a.sh * * * * * sleep 30; sh /a.sh 12.多个任务在一条命令中配置 * * * * * sh /a.sh sh /b.sh 13.每年执行一次任务 @yearly sh /a.sh @yearly 类似于“0 0 1 1 *”。它会在每年的第一分钟内执行,通常我们可以用这个发送新年的问候。 14.系统重启时执行 @reboot sh /a.sh 15.将 Cron 结果重定向的特定的账户 默认情况下,cron 只会将结果详情发送给 cron 被制定的用户。如果需要发送给其他用户,可以通过如下的方式: # crontab -l MAIL=bob 0 2 * * * /script/backup.sh -
实战演练:
- 项目需求:自动备份CAM资料库近三天有修改保存的料号(增量备份)
- 执行时间:午夜00:30,中午12:30,下午18:00(每天三次)
- 执行权限:root管理员用户
- 执行模式:全自动执行
- 信息推送:邮件&企业微信消息推送
- 参考项目<PCB制前工程CAM资料日备份项目制作>
课后作业:
- 编写一个获取系统当前日期的脚本并自动发送邮件到指定邮箱
第3课.常用命令
-
Centos7常用终端指令:
CentOS7命令合集:查看网络博客1
CentOS7命令合集:查看网络博客2
示例cd #用法: cd 路径 #含义:(change directory,改变目录) #作用:用于切换当前的工作目录的 ls #用法: ls 路径 #含义:(打开目录) #作用:用于打开当前的工作目录或者指定目录 df #用法: df -h #含义:查看磁盘分区空间使用情况 #作用:检测磁盘空间使用情况 #案例:益阳磁盘空间检测报警(当被监控空间容量达到80%时自动发送邮件报警,达到98%时自动锁死CAM资料制作保存功能,避免爆盘) ps #用法 ps -ef | grep python3 #含义:查看包含python3字符的进程信息 #作用:清除死进程 #案例:清除后台僵死的python3脚本(根据进程信息,kill相关的进程PID) ln #用法 ln -s /opt/python/bin/python /usr/bin/mypython #含义:将/opt/python/bin/python解释器软链接为/usr/bin/mypython #作用:在不改变本身真实目录的情况下虚拟一个可用的路径或文件 #案例:将自己的anaconda虚拟的python3解释器做为系统下的python3使用(ln -s /opt/anaconda/envs/python3.7.5/bin/python /usr/bin/python3) su #用法 su incam #含义:切换到incam用户,当su后面不带任何参数时默认切换到root用户 #作用:在一个终端下进入不同的用户并进行相关操作 #案例:切换到普通用户incam cp #用法 cp 指定文件 新文件 cp /tmp/aaa /tmp/bbb #含义:将/tmp/aaa文件复制出一个/tmp/bbb文件 #作用:复制文件或路径 #案例:/ mv #用法 mv 指定文件 新文件 mv /tmp/aaa /tmp/bbb #含义:将/tmp下的aaa文件改名为bbb文件 #作用:修改文件(夹)名称,移动文件(夹) #案例:/ scp #用法 scp 服务器:目录文件 复制过来后存放的文件路径 scp 172.20.7.19:/tmp/aaa /tmp #含义:将172.20.7.19/tmp下的aaa文件复制到本机/tmp下 #作用:远程复制文件(夹)到本地 #案例:/ ssh #用法 ssh root@服务器IP地址 ssh root@172.20.7.19 #含义:以root用户远程访问172.20.7.19服务器终端 #作用:远程操作指定服务器终端 #案例:以X模式进入172.20.7.19远端服务器启动genesis(ssh incam@172.20.7.19 -X; get启动Genesis2000) rm #用法 rm 文件 rm -rf /tmp/aaa #含义:直接删除/tmp下aaa文件或者文件夹 #作用:删除指定文件(夹) #案例:/ touch #用法 touch 文件 touch /tmp/aaa #含义:在/tmp下新建一个aaa文件 #作用:新建文件 #案例:/ mkdir #用法 mkdir 文件夹 mkdir -p /tmp/aaa #含义:递归创建/tmp/aaa文件夹 #作用:新建文件夹 #案例:/ source #用法 source shell脚本文件 source /tmp/aaa.csh #含义:在当前环境直接获取/tmp/aaa.csh中定义的变量等 #作用:不执行脚本但能获取脚本中设定的变量 #案例:/ xdg-open #用法 xdg-open 软件启动文件 xdg-open aaa.pdf #含义:自动调用系统默认pdf软件打开aaa.pdf文件 #作用:自动打开不确定文件 #案例:/ -
实战演练:
- 项目需求:自动监控及预警CAM资料库&server目录磁盘空间
- 执行时间:早上08:00,中午12:00,下午17:30(每天三次)
- 执行权限:root管理员用户
- 执行模式:全自动执行
- 信息推送:邮件推送&自动锁定InCAM/InCAMPro料号保存机制
- 参考项目<Centos7下用Python写一个磁盘空间自动预警脚本>
课后作业:
- 自行收集更多的常用命令并按示例记录好常用案例
第4课.Vim编辑器
-
- vim基础操作
网络参数教程:VIM操作基础命令
- A.文件操作
-
(1).打开文件
VIM 使用 –o 或 –O 选项打开多个文件,其中 –o 表示垂直并排,例如 vim -o lesson4 lesson5 lesson6。大O表示水平排列
对于垂直并排的文件:使用 ctrl + w + 上、下方向,表示上、下切换文件;
对于水平并排的文件:使用 ctrl + w + 左、右方向,表示左、右切换文件。
退出动作是针对所有的(ALL):qa、qa!、wqa -
(2).退出、保存文件
按键 含义 :w filename 保存为filename文件名,filename为空保存当前文件 :q 退出编辑 :q! 放弃修改直接退出 :qa、qa!、wqa 退出所以文件 -
(3). vim键入shell命令
输入 :!ls / ,可以在切换到shell命令ls,查看root目录下文件列表
-
- vim基础操作
-
- 光标操作
按键 含义 h 左 j 下 k 上 l 右 -
- 插入模式
按键 含义 i 在光标的前边进入插入模式 I 在光标所在行的行首进入插入模式 a 在光标的后边进入插入模式 A 在光标所在行的行尾进入插入模式 o 在光标所在行的下方插入空行并进入插入模式 O 在光标所在行的上方插入空行并进入插入模式 s 删除光标指定的字符并进入插入模式 S 将光标所在行清除并进入插入模式 -
- 普通模式
-
(1). 通用操作
按键 含义 0 将光标定位到行首的位置 ^ 同上 $ 将光标定位到行尾的位置 b 将光标定位到光标所在单词的起始处 e 将光标定位到光标所在单词的结尾处 w 将光标定位到下一个单词的起始处(注意,是光标所在单词的下一个单词) gg 将光标定位到文件的开头 G 将光标定位到文件的末尾 u 撤销最后一次修改 U 撤销对整行的修改 Ctrl + r 恢复撤销的内容 Ctrl + g 查看文件名等状态 % 匹配(),[],{}的另一部分 -
(2).删除操作
按键 含义 d0 删除光标从当前位置(不包含)到该行行首的所有字符 d^ 同上 d$ 删除从光标当前位置(包含)到该行行尾的所有字符 db 删除从光标当前位置(不包含)到单词起始处的所有字符 de 删除从光标当前位置(包含)到单词结尾处的所有字符 dw 删除从光标当前位置(包含)到下个单词起始处的所有字符 dh 删除光标前面一个字符dl删除光标指定的字符 dj 删除光标所在行以及下一行的所有字符 dk 删除光标所在行以及上一行的所有字符 dd 删除光标所在行的所有字符 dgg 删除光标所在行(包含)到文件开头的所有字符 dG 删除光标所在行(包含)到文件末尾的所有字符 x 删除单个字符 可与数字进行组合,如3dj,表示删除光标下面3行 -
(3).复制、粘贴
按键 含义 y 复制命令 yy 复制当前行 p 将粘贴板内容粘贴到光标前 P 将粘贴板内容粘贴到光标后 r 替换命令,单个字符 可与数字进行组合,如3k向上移动3行
-
(4).查找、替换
按键 含义 /findcontent 光标将定位到光标开始时至查找到的第一个内容处。如需查找下一个,则按下enter键,按下n键查找下一个,按下N查找上一个 :行号 光标跳转到某行 :/s/old/new 将光标所在行的第一个 old 替换为 new :%s/old/new/g 替换整个文件中每个匹配的字符串 :%s/old/new/gc 在替换时vim咨询弹出 (y/n/a/q/l/E/Y) 确认信息:
y 表示替换
n 表示不替换
a 表示替换所有
q 表示放弃替换
l 表示替换第一个并进入插入模式
^E 表示用 Ctrl+e 来滚动屏幕
^Y 表示用 Ctrl+y 来滚动屏幕:5,13s/old/new/g 替换第 5 行到第 13 行之间的所有old为new :行号 光标跳转到某行 删除空格行:非编辑状态下输入: g/^$/d
删除行首空格:非编辑状态下输入: %s/^\s*//g
删除行尾空格:非编辑状态下输入: %s/\s*$//g
VIM删除空白行: 在命令状态下输入: :g/^\s*$/d
:g 代表在全文档范围内 ^代表行的开始 \s*代表空白字符 &代表行的结束 d代表删除 用//将3段代码隔开
-
- 可视模式
普通模式下按v键进入可视模式
可视模式下使用hjkl选中行,使用“数字 + >”,向右缩进数次。其中,>表示右缩进,<表示左缩进
课后作业:
- 使用VIM编辑器新建一个"/tmp/test"文件,分别执行写入,修改,复制,返回,重做,删除行操作并保存文本
- 在终端实际操作练习vim基本操作,熟练掌握最常用的vim操作指令
- 可视模式
第二章.开发环境配置
第5课.安装Anaconda3(Python3)
第1节.Windows下安装配置Anaconda3
-
1.Anaconda简介
Anaconda,一个开源的Python发行版本,可用于管理Python及其相关包,包含了conda、Python等180多个科学包及其依赖项。
网络教程地址:原文链接 -
2.运行环境
Windows11 (Window10用户亦可参考,仅环境变量打开位置不同)。 -
3.安装Anaconda
-
(1).百度“Anaconda”或者输入网址“https://www.anaconda.com/”进入Anaconda官网。

默认版本为Windows,点击“Download”即可下载 。
-
(2).下载完成后双击“Anaconda3-2022.10-Windows-x86_64.exe”进行安装。

-
(3).点击“Next”。

-
(4).点击“I Agree”。

-
(5).点击“Just Me” 之后点击“Next”。(如果电脑有多个用户,选择“All User”)。

-
(6).设置安装路径,最好为全英文且文件夹需为空,之后点击“Next”。

-
(7).选择手动安装路径,之后点击“Install”。(因为上一个Anaconda也是手动添加路径,本次依然选择手动添加,大家有兴趣的也可尝试上面的自动添加路径。)

-
(8).点击“Next”。

-
(9).点击“Next” 。

-
(10).点击“Finish”。

到这里Anaconda已经安装完成了,接下来到配置环境变量。
-
-
4.手动配置环境变量(重点)
- (1).打开“此电脑”,右键点击“属性”,选择“高级系统设置”,点击“环境变量”。


- (2).在系统变量中找到“Path”(注意是区分是系统变量,不是环境变量;个别电脑“Path”可能大小写不同,但都是一样的,只是书写方式不同。)

- (3).双击“Path”,新建环境变量。
分三次输入以下信息(按自己实际安装路径输入):
Anaconda安装路径
Anaconda安装路径\Scripts
Anaconda安装路径\Library\bin

上图所示为个人安装路径,三条变量信息新建完成后点击“确定”。
- (1).打开“此电脑”,右键点击“属性”,选择“高级系统设置”,点击“环境变量”。
-
5.测试Anaconda环境是否配置成功
- (1).WIN+R打开cmd。

- (2).输入“conda --version”。(查看conda版本)

- (3).输入“conda info”。

- (4).输入“activate”,回车。之后输入“python”。

如果输出内容与上图类似(可能版本号不同),则说明环境变量配置成功。
至此,Anaconda安装已全部完成。
- (1).WIN+R打开cmd。
第2节.CentOS 7下安装配置Anaconda3
网络教程地址:原文链接
-
1.Anaconda下载
进入anaconda官方网站下载个人免费版本,网站链接,点击download,选择Linux平台的安装包

-
2.Anaconda安装
-
(1).执行如下指令,安装anaconda
# 进入当保存文件的目录,执行此指令, 后期由于版本更新,可能会与此文件命名有所不同 bash Anaconda3-2020.11-Linux-x86_64.sh -
(2).按照安装提示,键入回车
Please, press ENTER to continue >>> ENTER -
(3).安装此版本时,会强制用户看完整个协议,直接一路回车就行,直到看到确认信息
# 输入yes,表示同意安装协议 Do you accept the license terms? [yes|no][no] >>> yes
-
(4).确认安装路径(可修改,也可以使用自定义)
# 使用默认路径,直接键入回车,使用自定义路径,直接输入安装路径 # 此处使用 /opt/anaconda3作为安装路径 Anaconda3 will now be installed into this location: /root/anaconda3 - Press ENTER to confirm the location - Press CTRL-C to abort the installation - Or specify a different location below [/root/anaconda3] >>> /opt/anaconda3
注:安装位置可以在执行安装脚本的时候直接指定,可以这样修改执行内容:
bash Anaconda3-2020.11-Linux-x86_64.sh -p /opt/anaconda3这样可跳过软件安装路径确认阶段,直接安装到指定目录下。
-
(5).环境变量初始化
# 此处询问是否初始化conda的环境,直接输入yes Do you wish the installer to initialize Anaconda3 by running conda init? [yes|no][no] >>> yes
安装完成

-
(6).初始化时,anaconda将配置写入了~/.bashrc 文件,直接执行
source ~/.bashrc后即可正常使用了。
-
(7).配置多用户使用
将anaconda初始化时,写入到 ~/.bashrc 文件中的内容复制到 /etc/bashrc 文件中,内容如下(此处仅为示例,请复制本机对应文件中的相应内容)# >>> conda initialize >>> # !! Contents within this block are managed by 'conda init' !! __conda_setup="$('/opt/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" if [ $? -eq 0 ]; then eval "$__conda_setup" else if [ -f "/opt/anaconda3/etc/profile.d/conda.sh" ]; then . "/opt/anaconda3/etc/profile.d/conda.sh" else export PATH="/opt/anaconda3/bin:$PATH" fi fi unset __conda_setup # <<< conda initialize <<<
再执行 source /etc/bashrc 指令即可。
-
-
3.配置镜像源
-
3.1.conda配置镜像源:
使用conda进行安装时,访问的是国外的网络,所以下载和安装包时会特别慢。我们需要更换到国内镜像源地址,这里我更换到国内的清华大学地址。(永久添加镜像)
Windows和Linux 对于conda修改镜像源的方法一样-
(1).查看anaconda中已经存在的镜像源
conda config --show channels
-
(2).添加镜像源(永久添加)
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
-
(3).设置搜索时显示通道地址
conda config --set show_channel_urls yes -
(4).若不想按照上述步骤添加镜像,可使用以下命令直接指定安装时使用的镜像地址(以opencv为例):
conda install opencv -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
-
(5).添加完后查看
conda config --show channels
-
-
3.2.pip使用国内镜像源:
一般在使用conda install安装时会出现包无法找到或者安装失败的情况,此时可以使用pip install来尝试安装(以opencv为例):pip install opencv若安装速度过慢可单独指定安装镜像加快安装:
pip install opencv -i https://mirrors.aliyun.com/pypi/simple/此处列举国内常用pip安装镜像:
清华:https://pypi.tuna.tsinghua.edu.cn/simple
阿里云:https://mirrors.aliyun.com/pypi/simple
中国科技大学: https://pypi.mirrors.ustc.edu.cn/simple
华中理工大学:https://pypi.hustunique.com
山东理工大学:https://pypi.sdutlinux.org
豆瓣:https://pypi.douban.com/simplechannels: - defaults show_channel_urls: true default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/ custom_channels: conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
-
-
4.root用户安装的anaconda如何给普通用户使用
服务器里安装了anaconda,结果发现只有root用户才能使用,其他的用户都无法使用conda命令!
【解决方案】
首先,root用户安装anaconda的时候,需要安装在普通用户可以访问的目录下,比如/usr/local、/opt、/home之类的
其次,普通用户登陆后,需要执行以下conda init 使conda的路径等系统环境变量信息写入当前用户的bashrc下
例:
anaconda 装在了 (需要查看anaconda3安装路径)/opt/anaconda3普通用户 需要执行
/opt/anaconda3/bin/conda init bash
你需要根据自己的实际情况修改bin之前的目录
普通用户再执行启用配置命令source ~/.bashrc然后重新连接SSH (推荐)
或者
即使你没有重新连接ssh也可以通过(没试过)source activate base或
conda activate base能正常使用conda后,你就可以创建你自己的环境了,例
conda create -n xxx python=3.7环境会装在home中你的用户文件夹下,可以通过
conda env list查看对应的地址
以上操作的问题是,那个用户需要使用conda,就需要按以上步骤执行一遍,并没有设置成所有用户都可以调用的方式。
课后作业:
- 在Windows上安装并配置好Anaconda3,虚拟出Python3.7.5环境
- 在Centos 7上安装并配置好Anaconda3,虚拟出Python3.7.5环境
第6课.常用的Python模块安装
- 1.安装python模块
-
PyQt5图像界面模块安装
使用conda安装
(1).激活环境(例如:需要在已虚拟好的python3.7.5下安装)conda activate python3.7.5退出虚拟环境可以使用conda deactivate命令
(2).安装PyQt5模块conda install PyQt5(3).验证PyQt5模块是否安装成功(如下:进入python解释器,导入安装的PyQt5模块,没有任何提示信息表示安装成功)
python3.7.5 >>> import PyQt5 >>>使用pip安装
pip install PyQt5 -
pymysql/pymssql数据库操作模块安装
使用conda安装
(1).激活环境(例如:需要在已虚拟好的python3.7.5下安装)conda activate python3.7.5退出虚拟环境可以使用conda deactivate命令
(2).安装pymysql/pymssql模块conda install pymysql(3).验证pymysql/pymssql模块是否安装成功(如下:进入python解释器,导入安装的pymysql模块,没有任何提示信息表示安装成功)
python3.7.5 >>> import pymysql >>> -
xlrd/xlwt/xlutils库安装
(1).激活环境(例如:需要在已虚拟好的python3.7.5下安装)conda activate python3.7.5退出虚拟环境可以使用conda deactivate命令
(2).安装xlrd/xlwt/xlutils模块conda install xlrd(3).验证xlrd/xlwt/xlutils模块是否安装成功(如下:进入python解释器,导入安装的xlrd模块,没有任何提示信息表示安装成功)
python3.7.5 >>> import xlrd >>>
-
课后作业:
- 使用conda自行安装一款python第三方库
- 使用pip安装python开发需要的第三方库
第7课.安装集成开发工具(PyCharm)
-
系统要求
在安装 Pycharm 之前,请确保您的计算机满足以下系统要求:- Windows:Windows 7 或更高版本(64 位)。
- macOS:macOS 10.13 或更高版本。
- Linux:GNOME、KDE 或 XFCE(64 位)。
-
下载 Pycharm
-
- 打开浏览器,访问 JetBrains 官方网站。
-
- 在页面上找到“Download”按钮,点击进入下载页面。

- 在页面上找到“Download”按钮,点击进入下载页面。
-
- 根据您的操作系统,选择相应的版本进行下载。Pycharm 提供了专业版(Professional)和社区版(Community),专业版功能更丰富,但需要付费订阅,社区版则是免费开源的,对于大多数初学者和普通开发者来说,社区版已经足够使用。

- 根据您的操作系统,选择相应的版本进行下载。Pycharm 提供了专业版(Professional)和社区版(Community),专业版功能更丰富,但需要付费订阅,社区版则是免费开源的,对于大多数初学者和普通开发者来说,社区版已经足够使用。
-
-
安装 Pycharm(以 Windows 为例)
-
- 找到下载好的 Pycharm 安装程序(.exe 文件),双击运行。
-
- 在欢迎界面中,点击“Next”。
-
- 选择安装路径。建议您选择非系统盘(如 D 盘)的目录进行安装,以避免占用系统盘过多空间。点击“Browse”选择安装目录后,点击“Next”。
-
- 选择安装选项。您可以根据自己的需求选择创建桌面快捷方式、关联文件类型等选项。一般情况下,保持默认设置即可。点击“Next”。
-
- 选择开始菜单文件夹。默认情况下,Pycharm 会在开始菜单中创建一个文件夹,您也可以修改文件夹名称或选择不创建。点击“Install”开始安装。
-
- 安装过程可能需要一些时间,请耐心等待。安装完成后,点击“Finish”。
-
-
首次运行 Pycharm
-
- 安装完成后,如果您在安装过程中选择了创建桌面快捷方式,可以直接双击桌面上的 Pycharm 图标启动;否则,可以在开始菜单中找到 Pycharm 并点击启动。
-
- 首次运行 Pycharm 时,会弹出一个对话框,询问您是否要导入之前的设置。如果您是首次使用 Pycharm,可以选择“Do not import settings”,然后点击“OK”。
-
- 接下来,会弹出一个许可证激活对话框。如果您使用的是社区版,直接点击“Evaluate for free”即可开始免费试用;如果您有专业版的许可证,可以点击“Activate”并输入许可证信息进行激活。
-
-
配置 Pycharm
-
- 项目设置
点击“Create New Project”创建一个新项目。在弹出的对话框中,选择项目的存储路径、Python 解释器等信息。如果您已经安装了 Python,可以在“Python Interpreter”下拉列表中选择对应的解释器;如果没有安装,Pycharm 会提示您安装。点击“Create”创建项目。
- 项目设置
-
- 界面设置
Pycharm 的界面可以根据您的喜好进行定制。您可以通过“View”菜单中的选项来显示或隐藏各种工具窗口,如项目窗口(Project)、代码编辑器(Editor)、终端(Terminal)等。
在“Settings”(Windows 下为“File”->“Settings”,macOS 下为“Pycharm”->“Preferences”)中,您可以进一步配置 Pycharm 的各种功能,如代码风格、编辑器字体、快捷键等。
- 界面设置
-
-
至此,Pycharm 已经安装并配置完成,您可以开始使用它进行 Python 项目的开发了。
第8课.安装数据库(MySQL/SQLServer)
- 本人开发数据库主要使用MySQL8,以此为例(CentOS7安装配置MySQL8)
原文参考链接-
下载mysql安装包,复制安装包到CentOS7共享目录



下载哪个版本,首先需要确定一下系统的glibc版本,使用如下命令:rpm -qa | grep glibc


cp /你的下载文件目录/mysql-8.0.39-linux-glibc2.17-x86_64.tar /opt -
检查是否安装mysql
ps:因为以前用yum安装过,所以先用yum卸载。如果不是此方式或者没安装过则跳过
[root@localhost ~]# yum remove mysql # 已加载插件:fastestmirror # 参数 mysql 没有匹配 # 不删除任何软件包查看是否有mysql依赖
[root@localhost ~]# rpm -qa | grep mysql如果有则卸载
# 普通删除模式 rpm -e xxx(mysql_libs) # 强力删除模式,如果上述命令删除时,提示有依赖其他文件,则可以用该命令对其进行强力删除 rpm -e --nodeps xxx(mysql_libs) -
检查是否有mariadb
[root@localhost ~]# rpm -qa | grep mariadb mariadb-libs-5.5.68-1.el7.x86_64如果有则卸载
[root@localhost ~]# rpm -e --nodeps mariadb-libs [root@localhost ~]# rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_64 错误:未安装软件包 mariadb-libs-5.5.68-1.el7.x86_64 -
安装mysql依赖包
[root@localhost home]# yum install libaio -
解压
进入/opt目录下将mysql文件解压[root@localhost home]# cd /opt [root@localhost opt]# tar -xvf mysql-8.0.36-linux-glibc2.17-x86_64.tar mysql-test-8.0.36-linux-glibc2.17-x86_64.tar.xz mysql-8.0.36-linux-glibc2.17-x86_64.tar.xz mysql-router-8.0.36-linux-glibc2.17-x86_64.tar.xz [root@localhost opt]# tar -Jxvf mysql-8.0.36-linux-glibc2.17-x86_64.tar.xz [root@localhost opt]# mv mysql-8.0.36-linux-glibc2.17-x86_64 mysql按照习惯,我们将文件移动到/usr/local目录下
[root@localhost opt]# mv /opt/mysql/ /usr/local/我们切换到usr/local/目录下查看mysql是否存在
[root@localhost opt]# cd /usr/local/ [root@localhost local]# ll 总用量 0 drwxr-xr-x. 2 root root 6 4月 11 2018 bin drwxr-xr-x. 2 root root 6 4月 11 2018 etc drwxr-xr-x. 2 root root 6 4月 11 2018 games drwxr-xr-x. 2 root root 6 4月 11 2018 include drwxr-xr-x. 2 root root 6 4月 11 2018 lib drwxr-xr-x. 2 root root 6 4月 11 2018 lib64 drwxr-xr-x. 2 root root 6 4月 11 2018 libexec drwxr-xr-x. 9 root root 129 4月 2 21:20 mysql drwxr-xr-x. 11 root root 151 8月 28 2023 nginx drwxr-xr-x. 2 root root 6 4月 11 2018 sbin drwxr-xr-x. 5 root root 49 8月 29 2023 share drwxr-xr-x. 2 root root 6 4月 11 2018 src创建数据库文件存放的文件夹。这个文件夹将来存放每个数据库的库文件
[root@localhost local]# cd mysql [root@localhost mysql]# ls bin docs include lib LICENSE man README share support-files [root@localhost mysql]# mkdir mysqldb -
mysql安装目录赋予权限
[root@localhost mysql]# chmod -R 777 /usr/local/mysql/ -
创建mysql组和用户
创建组[root@localhost mysql]# groupadd mysql创建用户(-s /bin/false参数指定mysql用户仅拥有所有权,而没有登录权限)
[root@localhost mysql]# useradd -r -g mysql -s /bin/false mysql将用户添加到组中
[root@localhost mysql]# chown -R mysql:mysql ./ -
修改mysql配置文件
[root@localhost mysql]# vi /etc/my.cnf将里面的命令都删除掉,然后添加以下命令,保存并退出(如果有一定经验,可以在里面添加一些其他的配置)
[mysqld] # 设置3306端口 port=3306 # 设置mysql的安装目录 basedir=/usr/local/mysql # 设置mysql数据库的数据的存放目录 datadir=/usr/local/mysql/mysqldb # 允许最大连接数 max_connections=10000 # 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统 max_connect_errors=10 # 服务端使用的字符集默认为UTF8 character-set-server=utf8 # 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB # 默认使用“mysql_native_password”插件认证 default_authentication_plugin=mysql_native_password [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 [client] # 设置mysql客户端连接服务端时默认使用的端口 port=3306 default-character-set=utf8 -
安装mysql
进入mysql 安装目录下:[root@localhost mysql]# cd /usr/local/mysql/bin/安装mysql,并记住初始化随机密码
[root@localhost bin]# ./mysqld --initialize --console 2024-04-02T13:25:55.133890Z 0 [Warning] [MY-010918] [Server] 'default_authentication_plugin' is deprecated and will be removed in a future release. Please use authentication_policy instead. 2024-04-02T13:25:55.133913Z 0 [System] [MY-013169] [Server] /usr/local/mysql/bin/mysqld (mysqld 8.0.36) initializing of server in progress as process 2186 2024-04-02T13:25:55.139191Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous. 2024-04-02T13:25:55.154304Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started. 2024-04-02T13:25:55.706150Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended. 2024-04-02T13:25:57.058187Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: <;cdUJXy!91b 2024-04-02T13:25:57.159383Z 6 [Warning] [MY-013360] [Server] Plugin mysql_native_password reported: ''mysql_native_password' is deprecated and will be removed in a future release. Please use caching_sha2_password instead'
-
启动mysql服务
进入mysql.server服务目录下并启动服务[root@localhost bin]# cd /usr/local/mysql/support-files [root@localhost support-files]# ./mysql.server start Starting MySQL.Logging to '/usr/local/mysql/mysqldb/localhost.localdomain.err'. ERROR! The server quit without updating PID file (/usr/local/mysql/mysqldb/localhost.localdomain.pid).如果第一次启动,当初始化执行会有报错
此时不要担心,重新给mysql安装目录赋予一下权限后,再次执行。[root@localhost support-files]# chmod -R 777 /usr/local/mysql [root@localhost support-files]# ./mysql.server start Starting MySQL. SUCCESS! -
将mysql添加到系统进程中
[root@localhost support-files]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld此时我们就可以使用服务进程操作mysql了
-
设置mysql自启动
[root@localhost support-files]# chmod +x /etc/init.d/mysqld [root@localhost support-files]# systemctl enable mysqld mysqld.service is not a native service, redirecting to /sbin/chkconfig. Executing /sbin/chkconfig mysqld on此时mysql自启动就已经设置好了
-
修改root用户登录密码
登录mysql[root@localhost support-files]# cd /usr/local/mysql/bin/ [root@localhost bin]# ./mysql -u root -p执行后,输入我们初始化时记录下的随机密码,就会进入mysql。
修改密码:mysql> alter user 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456'; Query OK, 0 rows affected (0.01 sec) -
设置允许远程登录
mysql> use mysql Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> update user set user.Host='%'where user.User='root'; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) mysql> quit Bye -
重启服务且测试
centos6与centos7的服务命令都支持[root@localhost bin]# systemctl restart mysql [root@localhost bin]# service mysql restart Redirecting to /bin/systemctl restart mysql.service查看mysql是否启动
systemctl status mysql查看防火墙开放端口
[root@localhost bin]# firewall-cmd --list-all在防火墙中将3306端口开放
[root@localhost bin]# firewall-cmd --zone=public --add-port=3306/tcp --permanent success //--permanent为永久生效,没有此参数 服务器重启后配置失效 [root@localhost bin]# firewall-cmd --reload success在Navicat上测试连接

重启linux后测试自启动(可选)[root@localhost bin]# reboot测试mysql服务是否自启动

测试远程访问

-
第9课.安装navicat(数据库操作客户端)
- 下载安装包
官网下载 - 安装
除了更改安装路径和生成桌面快捷方式外,其余按照默认步骤安装即可,建议安装在 D 盘,如下图:

询问是否生成桌面安装方式时,选上,如下图:
注意:安装完成先不要打开运行navicat
- 激活
由于版权原因,此处不便复述,请购买正版软件或者
参考博文1
参考博文2
自行处理
第10课.CAM软件脚本语言环境配置
- 步骤1. 找到InCAMPro编程语言环境配置脚本:
配置脚本路径:/incam/release/app_data/scr_start.csh,release根据自己公司绑定的版本目录

脚本代码:#!/bin/csh # # Date : 12 Jan 1994 # Version : 1 MK # # 11/09/2005 IL: Modified to suit InCAM variables # Some of the 'if's are no longer relevant, but kept anyway, # perhaps they will be relevant for Unix installations. # # 24/05/2007 Mikets: Added support for Python scripts # if($?INCAM_SERVER)then set _incam_root="$INCAM_SERVER" else set _incam_root=/incam endif if($?INCAM_PRODUCT)then set __incam_prod="$INCAM_PRODUCT" else set __incam_prod="$_incam_root/release" endif if ($?windir) then set sep=";" else set sep=":" endif if("$__incam_prod" =~ /* || "$__incam_prod" =~ ?:*)then setenv PATH "$__incam_prod/utils$sep$PATH" else setenv PATH "$_incam_root/$__incam_prod/utils$sep$PATH" endif set STATUS=0 set PROG=$1 if(! -e $PROG)then set PROG_STATUS=1 goto end endif # define aliases set DIR_PREFIX='@%#%@' alias VON 'echo "${DIR_PREFIX}VON";' alias VOF 'echo "${DIR_PREFIX}VOF";' alias SU_ON 'echo "${DIR_PREFIX}SU_ON";' alias SU_OFF 'echo "${DIR_PREFIX}SU_OFF";' alias PAUSE 'echo "${DIR_PREFIX}PAUSE \!:*"; \\ set STATUS=$<; set READANS=$<; set PAUSANS=$<; \\ if ($PAUSANS != "OK") exit' alias MOUSE 'echo "${DIR_PREFIX}MOUSE \!:*"; \\ set STATUS=$<; set READANS=$<; set MOUSEANS="$<"' alias COM 'echo "${DIR_PREFIX}COM \!:*"; \\ set STATUS=$<; set READANS="$<"; set COMANS=($READANS)' alias AUX 'echo "${DIR_PREFIX}AUX \!:*"; \\ set STATUS=$<; set READANS="$<"; set COMANS=($READANS)' set argv = ($2) set IFILE = $INCAM_TMP/info.$$ alias DO_INFO 'COM info,out_file=$IFILE,write_mode=replace,args= \!:* ; source $IFILE; rm $IFILE' #executing hook script set _user_done=0 if($?INCAM_USER_DIR)then if(-e $INCAM_USER_DIR/hooks/script_start.csh)then source $INCAM_USER_DIR/hooks/script_start.csh set _user_done=1 endif endif if($_user_done != "1")then if(-e $_incam_root/site_data/hooks/script_start.csh)then source $_incam_root/site_data/hooks/script_start.csh endif endif # check first line of program #set _HEAD=`head -1 $PROG` Yefim 02.06.04 set _HEAD=`sed -n 1p $PROG` set _END = `echo $PROG:e` if ("$_HEAD" =~ *perl*) then # 当用perl编写脚本程式时,首行包含"perl"将调用perl解释器执行代码 echo "Executing Perl Program $PROG $argv" perl $PROG $argv set PROG_STATUS=$status else if ("$_HEAD" =~ *python*) then # 当用Python编写脚本程式时,首行包含"python"将调用python解释器执行代码 echo "Executing Python Program $PROG $argv" /usr/bin/python3 $PROG $argv set PROG_STATUS=$status else if ("$_HEAD" =~ *py3k*) then # 当用自定义的Python版本或者环境编写脚本程式时,首行包含"py3k"将调用自定义环境下的python解释器执行代码 echo "Executing Python Program $PROG $argv" /usr/bin/py3k $PROG $argv set PROG_STATUS=$status else if ("$_HEAD" =~ *wish*) then # 当用tcl编写脚本程式时,首行包含"wish"将调用tcl解释器执行代码 setenv TCSHONLYSTARTEXES 1 echo "Executing TCL Program $PROG $argv" $_incam_root/site_data/hooks/wish_start.tcl $PROG $argv set PROG_STATUS=$status else if ("$_END" =~ [Pp][Yy][Cc]) then # 当用python编写脚本程式并使用生成的pyc执行时,文件后缀包含"pyc"将调用python解释器执行pyc文件 echo "Executing Python PYC Program $PROG $argv" /usr/bin/python3 $PROG $argv set PROG_STATUS=$status else # 默认执行C SHell代码 echo "Executing C Shell Program $PROG" source $PROG set PROG_STATUS=$status endif end: exit($PROG_STATUS) - 步骤2. 编写InCAMPro软件Python脚本接口(最新版的InCAMPro已经自带python接口):
python接口路径:/incam/release/app_data/python/incam.py(没有接口也没关系这个是可以自己写的,参考perl的代码直接转写为python代码,效果是一样的,也可以参考我提供给大家的源码!
接口代码:
有了这些就可以用python自由编写InCAMPro的脚本代码了,当然,我们实际的工作中去实现我们的脚本逻辑一般会在这个基础的接口上进行更加个性化及抽象化的封装,尽可能的让我们的脚本逻辑清晰代码简洁,此处不做过多复述,后续课程我们会着重讲解自定义接口包的封装!#!/usr/bin/env python '''Package for running Python programs in a InCAM/InCAMPro environment. ''' import sys, re import time import os import socket import io import string # In order to support both python2 and python3 if sys.version_info[0] < 3: input = raw_input python_version = 2 # reload(sys) # sys.setdefaultencoding('utf-8') else: python_version = 3 sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8') class InCAM: def __init__(self, remote='127.0.0.1'): """ Initialize the class """ self.prefix = '@%#%@' self.blank() self.pid = os.getpid() tmp = 'incam_'+ str(self.pid)+'.'+str(time.time()) if 'TMP' in os.environ.keys(): self.tmpfile = os.path.join(os.environ['TMP'], tmp) self.tmpdir = os.environ['TMP'] else: self.tmpfile = os.path.join('/tmp', tmp) self.tmpdir = '/tmp' self.comms = 'pipe' self.port = 'flsport' self.socketOpen = 0 self.remote = remote try: if sys.stdin.isatty() or 'INCAM_USER' not in os.environ.keys(): self.comms = 'socket' self.openSocket() self.socketOpen = 1 self.inheritEnvironment() except: pass def closeDown(self): self.sendCmd("CLOSEDOWN", "") def inheritEnvironment(self): self.sendCmd("GETENVIRONMENT", "") while 1: reply = self.getReply().strip() if reply == 'END': break var,value = reply.split('=',1) os.environ[var]=value def openSocket(self): self.socketOpen += 1 if self.socketOpen != 1: return port = self.port remote = self.remote try: if re.match(r'\D+',port): port = socket.getservbyname(port, 'tcp') except: port = 56753 self.SOCK = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.SOCK.connect((remote,port)) self.sf = self.SOCK.makefile('rw') def sendCmd(self, cmd, args=''): self.blank() if self.comms == 'pipe': self.sendCommandToPipe(cmd, args) if self.comms == 'socket': self.sendCommandToSocket(cmd, args) def sendCommandToPipe(self,cmd, args=''): ''' Send the commands to stdout ''' wsp = ' '*(len(args)>0) cmd = self.prefix + cmd + wsp + args + '\n' # sys.stdout.write(cmd.encode('utf8')) # if python_version == 2: sys.stdout.write(cmd) sys.stdout.flush() return 0 def sendCommandToSocket(self, cmd, args=''): ''' Send the commands to Socket ''' wsp = ' '*(len(args)>0) cmd = self.prefix + cmd + wsp + args + '\n' self.sf.write(cmd) self.sf.flush() def getReply(self): if self.comms == 'pipe': reply = input() if self.comms == 'socket': reply = self.sf.readline() return reply def __del__(self): ''' Called when class is cleaned up by python ''' if os.path.isfile(self.tmpfile): os.unlink(self.tmpfile) if (self.socketOpen == 0): return self.sf.write(self.prefix + 'CLOSEDOWN\n') self.sf.flush() self.sf.close() self.SOCK.close() def blank(self): ''' Initiate the return values ''' self.STATUS = 0 self.READANS = '' self.COMANS = '' self.PAUSANS = '' self.MOUSEANS = '' def SU_ON(self): print("") return self.sendCmd('SU_ON') def SU_OFF(self): print("") return self.sendCmd('SU_OFF') def VON(self): print("") return self.sendCmd('VON') def VOF(self): print("") return self.sendCmd('VOF') def PAUSE(self, msg): self.sendCmd('PAUSE', msg) self.STATUS = int(self.getReply()) self.READANS = self.getReply() self.PAUSANS = self.getReply() #solve the print message to terminal issues: some message can't be printed. print("") return self.STATUS def MOUSE(self, msg, mode='p'): self.sendCmd('MOUSE ' + mode, msg) self.STATUS = int(self.getReply()) self.READANS = self.getReply() self.MOUSEANS = self.getReply() return self.STATUS def COM(self, args): self.sendCmd('COM', args) self.STATUS = int(self.getReply()) self.READANS = self.getReply() self.COMANS = self.READANS[:] # self.COMANS = self.COMANS.strip() #solve the print message to terminal issues: some message can't be printed. print("") return self.STATUS def AUX(self, args): self.sendCmd('AUX', args) self.STATUS = int(self.getReply()) self.READANS = self.getReply() self.COMANS = self.READANS[:] # self.COMANS = self.COMANS.strip() #solve the print message to terminal issues: some message can't be printed. print("") return self.STATUS # --- INFO methods --- # Get some basic info # It is received in the form of a csh script, so the information needs parsed to suit for python def INFO(self, args): self.COM('info,out_file=%s,write_mode=replace,args=%s' % (self.tmpfile, args)) lineList = open(self.tmpfile, 'r').readlines() os.unlink(self.tmpfile) return lineList #Get InCAMPro info in imperial unit def DO_INFO(self, args): self.COM('info,out_file=%s,write_mode=replace,args=%s' % (self.tmpfile, args)) lineList = open(self.tmpfile, 'r').readlines() os.unlink(self.tmpfile) infoDict = self.parseInfo(lineList) return infoDict #Get InCAMPro info in metric unit def DO_INFO_MM(self, args): self.COM('info,out_file=%s,write_mode=replace,units=mm,args=%s' % (self.tmpfile, args)) lineList = open(self.tmpfile, 'r').readlines() os.unlink(self.tmpfile) infoDict = self.parseInfo(lineList) return infoDict def convertToNumber(self, value): try: return string.atoi(value) except: try: return string.atof(value) except: return value def parseInfo(self, infoList): parseDict = {} for line in infoList: line=line.strip() keywithval = line.split(' = ', 1) if len(keywithval) == 2: key = keywithval[0].strip()[4:] val = keywithval[1] allValList = val.split("'") valList = [] if allValList[0] == '(': allValList = allValList[1:-1] for i in range(allValList.__len__()): if allValList[i] == '': valList.append('') elif re.match(r'^\s+$',allValList[i]): continue else: valList.append(allValList[i]) elif allValList[0] =='()': valList=[] else: if allValList.__len__() == 1: valList=self.convertToNumber(allValList[0]) if allValList.__len__() == 3: valList=self.convertToNumber(allValList[1]) parseDict[key] = valList return parseDict
使用案例代码:#!/usr/bin/python import os import re import sys #add python lib path to search path, so that incam class can be imported sys.path.append(os.environ['INCAM_PRODUCT']+'/app_data/python') import incam # get JOB, STEP variable f = incam.InCAM() job=os.environ['JOB'] step=os.environ['STEP'] #DO_INFO example info = f.DO_INFO('-t matrix -e ' + job + '/matrix') #INFO example, used only when the output is not in cshell format, #for example, get measures result from one checklist #info = f.INFO("-t check -e "+ job + "/" + step + "/checklist -d MEAS") for lay in info['gROWname']: #do some regulation express filter if re.search('\+{3}$',lay): f.COM('delete_layer, layer=' + lay) #PAUSE command f.PAUSE("layer "+lay+"is deleted, please check!") exit()
第11课.Git安装配置
第1节. 安装 Git
-
Windows
- 访问 Git 官方下载页面:https://git-scm.com/download/win
- 下载适合您的 Windows 版本的 Git 安装包(32 位或 64 位)。
- 运行安装程序,按照提示完成安装,推荐使用默认设置。
-
macOS
- 使用 Homebrew 安装 Git(如果尚未安装 Homebrew):
brew install git - 或者访问 Git 官方下载页面:https://git-scm.com/download/mac,下载安装包进行安装。
- 使用 Homebrew 安装 Git(如果尚未安装 Homebrew):
-
Linux
在终端中运行以下命令安装 Git:
Ubuntu / Debian:sudo apt update sudo apt install gitCentOS / RHEL:
sudo yum install gitFedora:
sudo dnf install git
第2节. 配置 Git
安装完成后,进行一些基本配置。
-
配置用户名:
git config --global user.name "Your Name" -
配置用户邮箱:
git config --global user.email "youremail@example.com" -
设置默认编辑器(如使用 Vim):
git config --global core.editor vim -
检查配置:
git config --list
第3节. Git 基本命令
-
创建仓库
- 创建一个新的 Git 仓库:
git init - 克隆一个远程仓库:
git clone <repository-url>
- 创建一个新的 Git 仓库:
-
工作区与暂存区
- 查看文件状态:
git status - 将文件添加到暂存区:
git add <file>
- 查看文件状态:
-
提交更改:
git commit -m "Commit message" -
查看提交历史:
git log -
分支操作
- 创建新分支:
git branch <branch-name> - 切换分支:
git checkout <branch-name> - 创建并切换到新分支:
git checkout -b <branch-name> - 删除分支:
git branch -d <branch-name> - 合并分支:
git merge <branch-name> - 查看分支:
git branch
- 创建新分支:
-
远程仓库操作
-
添加远程仓库
- 添加远程仓库:
git remote add origin <repository-url> - 查看远程仓库:
git remote -v
- 添加远程仓库:
-
推送与拉取
- 推送代码到远程仓库:
git push origin <branch-name> - 从远程仓库拉取代码:
git pull origin <branch-name> - 推送所有标签:
git push --tags
- 推送代码到远程仓库:
-
拉取最新代码
- 拉取最新的代码并合并:
git pull origin master
- 拉取最新的代码并合并:
-
-
Git 进阶命令
-
Git Rebase
git rebase命令用于将一个分支的变更合并到另一个分支上,与git merge的区别在于,rebase会将提交的历史改写为线性。- 切换到需要变基的分支:
git checkout feature-branch - 执行变基操作:
git rebase master - 如果发生冲突,解决冲突后继续变基:
git add 冲突文件 git rebase --continue - 完成后,将变基后的分支推送到远程仓库:
git push origin feature-branch --force
- 切换到需要变基的分支:
-
Git Stash
git stash可以暂时保存当前工作目录的改动,以便切换到其他分支。- 保存当前修改:
git stash - 查看当前的 stash:
git stash list - 恢复最近保存的 stash:
git stash pop - 如果不再需要某个 stash,可以删除它:
git stash drop stash@{0}
- 保存当前修改:
-
Git 标签(Tag)
标签用于标记特定的提交,常用于发布版本。- 创建标签:
git tag v1.0.0 - 推送标签到远程仓库:
git push origin v1.0.0 - 查看所有标签:
git tag - 删除本地标签:
git tag -d v1.0.0
- 创建标签:
-
Git Submodule
Git 子模块用于在一个 Git 仓库中嵌套另一个 Git 仓库。- 添加子模块:
git submodule add <repository-url> <path> - 初始化子模块:
git submodule init - 更新子模块:
git submodule update
- 添加子模块:
-
-
参考资料
第12课.Svn安装配置
-
- 安装 SVN 程序
-
Windows
- 访问 SVN 官方下载页面:https://subversion.apache.org/packages.html。
- 下载适用于 Windows 的安装程序(例如:TortoiseSVN)。
- 运行安装程序,按照提示完成安装,推荐使用默认设置。
-
macOS
- 使用 Homebrew 安装 SVN(如果尚未安装 Homebrew):
brew install svn - 或者访问 SVN 官方下载页面:https://subversion.apache.org/packages.html,下载安装包进行安装。
- 使用 Homebrew 安装 SVN(如果尚未安装 Homebrew):
-
Linux
在终端中运行以下命令安装 SVN:- Ubuntu / Debian:
sudo apt update sudo apt install subversion - CentOS / RHEL:
sudo yum install subversion - Fedora:
sudo dnf install subversion
- Ubuntu / Debian:
-
- 配置 SVN 用户信息
安装完成后,需要配置 SVN 用户信息。
- 配置用户名:
svn propset svn:username "Your Name" <repository-path> - 配置用户邮箱:
svn propset svn:email "youremail@example.com" <repository-path> - 配置提交日志:
svn propset svn:log "Your commit message" <repository-path> - 检查配置:
svn info
- 配置 SVN 用户信息
-
- 上传并提交代码(SVN 代码托管平台)
- 上传本地代码到 SVN 仓库
- 创建本地工作副本:
svn checkout <repository-url> - 将代码添加到工作副本:
svn add <file-or-directory> - 提交更改到 SVN 仓库:
svn commit -m "Your commit message"
- 创建本地工作副本:
- 提交特定文件
- 如果只提交某些文件,可以指定文件名:
svn commit <file1> <file2> -m "Commit message for specific files"
- 如果只提交某些文件,可以指定文件名:
-
- 下载托管的代码(SVN 代码托管平台)
- 获取 SVN 仓库代码
- 从远程 SVN 仓库检出代码:
svn checkout <repository-url> - 更新本地工作副本以获取最新的代码:
svn update - 检出指定的分支或标签:
svn checkout <repository-url>/branches/<branch-name>
- 从远程 SVN 仓库检出代码:
- 查看文件的历史记录
- 查看文件的修改历史:
svn log <file> - 查看目录的修改历史:
svn log <directory>
- 查看文件的修改历史:
-
- 参考资料
第三章.工程软件学习
第13课.Genesis2000/InCAM/InCAMPro安装配置
第1节.CentOS 7安装配置Genesis2000
-
步骤1.安装前准备工作(root用户):
- CentOS7安装wine工具:
yum install epel-release yum install wine - CentOS7安装依赖包:
yum install libX11.so.6 --setopt=protected_multilib=false - CentOS7字体安装:
yum install -y *org*font*
- CentOS7安装wine工具:
-
步骤2.安装Genesis2000:
-
复制安装文件到/opt/linux_genesis目录:

-
启动Genesis2000安装脚本install.csh安装程式:
cd /opt/linux_genesis/Genesis-Linux ls如图找到install.csh安装脚本文件
执行csh install.csh命令启动安装脚本csh install.csh如下图启动程式安装界面

如下图配置安装参数,单击"Load Installation Plug-in"

如下图单击"Server"进入下一步

如下图设置安装路径为"/frontline/app_gen",单击"Copy product files"进入下一步

如下分别在弹窗窗口依次点击"Yes,OK, YES, Genesis"等待当前步骤执行完成




当"Copy product files"完成后如下图显示

如下图单击"Set file permissions"进入下一步,完成后显示"Done"

如下图单击"Update license"进入下一步,完成后显示"Error"

注意:此步报错不必理会
如下图单击"Update startup files"进入下一步,弹出窗口单击"YES",然后在单击"OK"完成此步


完成后如下图显示

如下图单击"Set users/group"配置初始管理员用户及用户组

完成后如下图显示

单击"Set logical databases"设置库文件路径


完成后如下图显示

单击"Update O.S. Kernel"后进入下一步

单击"check installation"检查安装状况

完成后如下图显示

-
替换安装目录下的get及gnd程序及配置license文件:
- 替换get文件
cd /opt/linux_genesis ls cp get /frontline/app_gen/e100/get cp: 是否覆盖"/frontline/app_gen/e100/get/get" y - 替换gnd文件
cd /opt/linux_genesis ls cp gnd /frontline/app_gen/e100/gnd cp: 是否覆盖"/frontline/app_gen/e100/gnd/gnd" y - 配置license文件
cd /opt/linux_genesis ls cp GN00-9281-A8F9-CF68 /frontline/app_gen/share/license - 配置Genesis2000启动及运行环境:
创建/genesis软链接
配置genesis服务启动:ln -s /frontline/app_gen /genesis
安装依赖包
启动genesis服务:yum install libz.so.1 --setopt=protected_multilib=false yum install libfreetype.so.6
看到如下图所示表示gnd进程已启动:systemctl start genesis systemctl status genesis (查看服务状态) ps -ef|grep gnd (查看gnd进程是否已经启动")

- 启动Genesis2000,验证安装是否成功:
安装依赖包
root用户下验证启动Genesis2000:yum install libXp.so.6 -y yum install libXt.so.6 -y
输入账户密码成功后登入软件,如下图所示:cd /genesis/e100/get ./get

- 配置普通用户启动Genesis2000:
配置/genesis/init.csh初始化文件
如下图编辑init.csh文件内容后保存退出vim /genesis/init.csh

配置普通用户(例:incam) .cshrc环境变量加载文本
如下图编辑.cshrc文件内容vim /home/incam/.cshrc

配置普通用户(incam)默认使用csh
如下图编辑文本最后一行shell为/bin/cshvim /etc/passwd
配置.Xmodmap文档激活Genesis2000快捷键模式
如下图编辑.Xmodmap文本vim /home/incam/.Xmodmap

如下图注销普通用户后打开终端按提示启动Genesis2000

打开终端输入"get"后回车启动并登录Genesis2000
成功后如下图进入Genesis2000get

- 替换get文件
-
课后作业:
- 安装完成Linux版Genesis2000软件
- 配置普通用户登录Genesis2000
- 启动Genesis2000并创建一个料号
第2节.华为欧拉安装配置InCAMPro
- 安装InCAMPro:
-
复制安装文件到"/root/桌面"目录:

-
启动InCAMPro安装程式:
cd /root/桌面 ls如图找到InCAMPro-5.0SP4.364587-linux-x64-installer.run安装文件
执行修改安装文件权限命令并执行安装文件
chmod 777 InCAMPro-5.0SP4.364587-linux-x64-installer.run ./InCAMPro-5.0SP4.364587-linux-x64-installer.run如下图安装程序启动,单击"Next"进入下一步

如下图配置安装参数,单击"Next"

如下图选择要安装的类型,单击"Next"进入下一步,我们这里仅安装客户端及InLink模块

如下图设置安装路径为"/incampro",单击"Next"进入下一步

如下设置"/tmp"为临时目录,单击"Next"继续

如下设置"/incampro/server"为server目录,单击"Next"继续注意:需要先挂载服务端的server路径在设置的路径下,假设服务端IP是172.16.8.1,服务端的server目录在/opt/server目录,我们将服务端的server挂载到/incampro/server即可,没有成功挂载服务端server是无法继续往下安装客户端的
mount 172.16.8.1:/opt/server /incampro/server
如下图单击"Next"进入下一步

如下图需按Inplan的Oracle相关配置参数填写后单击"Install"进入下一步

注意:没有InPlan的不用安装InLink
如下图配置tnsnames.ora单击"Install"进入下一步

如下图单击"Install"等待安装程序执行



如下图单击"Finish"完成安装

-
配置InCAMPro:
-
将版本目录链接成release目录
cd /incampro ls ln -s /incampro/5.1SP2 /incampro/release -
配置普通用户(incam)目录.cshrc文件
cd /home/incam vim .cshrc输入以下内容,根据自身实际路径调整
# .cshrc rm -rf /home/incam/.history >& /dev/null source /incampro/server/init.csh setenv GTK_IM_MODULE ibus setenv QT_IM_MODULE ibus setenv XMODIFIERS @im=ibus setenv QT_NO_SESSION_MANAGEMENT 1 setenv INCAM_DIR /incampro setenv INCAM_TMP /incampro/tmp alias mesbox "python3 /incampro/server/site_data/scripts/CAM_public_system/mesbox.py" alias incam "/incampro/release/bin/incampro.csh" -
配置普通用户默认SHELL为csh
# 进入root用户 vim /etc/passwd # 找到"incam:x:1000:1000:incam:/home/incam"......这一行, # 改为"incam:x:1000:1000:incam:/home/incam:/bin/csh"后reboot重启系统, # 进入普通用户incam后"ECHO $SHELL"查看默认的SHELL是否修改ok
-
安装依赖包
yum install libXaw -
配置加密狗客户端:
# 启动配置页面 firefox如下图先选择中文环境后单击配置进入配置页面:

如下图配置用户页面

如下图配置访问远程授权管理器页面

如下图配置从客户端访问页面

-
重启系统并进入普通用户(incam),启动终端并输入incam回车,输入账号密码进入InCAMPro:
桌面右键->打开终端->输入incam->回车->输入账户/口令->进入InCAMPro
启动终端并输入incam回车启动
如下图输入账户/口令后回车启动InCAMPro
如下图进入InCAMPro

-
-
课后作业:
- 安装完成Linux版InCAMPro软件
- 配置普通用户登录InCAMPro
第14课.Genesis2000/InCAM/InCAMPro操作基础
第1节.Genesis2000操作基础
第2节.InCAM操作基础
第3节.InCAMPro操作基础
第15课.Genesis2000/InCAM/InCAMPro系统参数
-
1.Genesis2000的主要系统参数及管理目录说明:
-
Genesis2000软件目录图示:

-
系统结构及主要文件程式释义:
|e100 |---all |------errs |---------ALL_ERRS (软件所有报错弹窗信息分类汇总文档) |------fonts (软件自带字体存放目录) |---------canned_57 |---------canned_67 !---------...... |------helps |---------line (LMC文档<开发文档>存放目录) |------inlink (当MI使用inplan/inflow设计工程资料时可以通过inlink直接同步MI做好的特定资料到CAM料号下) |------markers (分孔图样式文件存放目录,允许自定义分孔图刀序样式) |------perl (perl语言接口存放位置,我们可以参照这些接口自定义其他开发语言的接口) |------pixmaps (一些软件用到的图片文件存放目录) |------scr_start.csh (脚本语言配置程式,我们在这里配置自己的脚本语言环境) |------sysattr (系统属性文件,我们一般不在这里自定义属性,因为这个文件会跟随版本一起升级) |---get |------get.exe (软件主程式) |---gfb |------gfb.exe (form窗口编辑主程式,已过时) |---gfl |------gfl.exe (flow流程配置主程式,已过时) |---gnd |------gnd.exe (软件主服务程式,如果当前程序不能运行将无法正常执行软件) |---misc |---prog(erf参数文档主目录,当系统sys下没有frontline_prog时软件默认读此路径) |------dfm (软件优化功能配置文件目录) |------cleanup(软件cleanup配置文件目录) |------analysis (软件分析功能配置文件目录) |fw |---jobs (odb++料号文件存放位置) |---lib (系统公共资源存放位置) |------flows (存放所有flows文件,已过时) |------forms (存放所有forms文件,已过时) |------fonts (字体存放目录, 优先读取库中的字体) |------fonts_ex (自定义的cad字体存放目录, 优先读取库中的字体) |---------shx (存放shx格式字体) |------------...... |---------ttf (存放ttf格式字体) |------------...... |------misc |---------userattr (自定义属性文件) |------symbols (系统symbol库) |------steps (存放一些公共的step,例如常用的coupon等) |------wheels (存放一些自定义的wheel文件) |logs (存放日志文件) |share |---.comms (存放加密狗相关的一些文件) |------gend_global (IP需指向加密狗服务器) |------gend_local (IP需指向加密狗服务器) |---license (存放授权文件) |---groups (用户组配置文件) |---joblist (料号清单文件) |---privs (权组配置文件) |---rcs (料号上锁清单文件) |---users (用户账户/明码配置文件) |---users97 ( 用户账户/密码配置文件) |sys |---frontline_prog (erf参数文档主目录,当系统sys下有frontline_prog时软件默认优先读此路径) |------dfm (软件优化功能配置文件目录) |------cleanup(软件cleanup配置文件目录) |------analysis (软件分析功能配置文件目录) |---hooks (软件钩子脚本目录汇总) |------ffilters (软件过滤器脚本配置目录) |---------names (过滤器功能清单) |---------script 过滤器功能配置脚本) |------line_hooks (软件lmc指令钩子脚本目录) |---------指令.pre (指令前置钩子脚本, 执行指令前先做什么) |---------指令.post (指令后置钩子脚本, 执行指令后再做什么) |------ncd (自动钻孔输出管理器钩子脚本及配置文件路径) |------ncr (自动锣带输出管理器钩子脚本及配置文件路径) |------acquire (自动备份导入配置脚本,较少使用) |------secure (自动备份导出配置脚本,较少使用) |------drill_size (自动补偿钻孔管理器钩子脚本) |------drill_size.tab (钻头配置文件) |------film_sizes (奥宝光绘机底片尺寸配置文件) |------lyr_rule (按厂内层别命名自动定义属性及排序配置文件) |------orbotech_plot_spool.config (奥宝光绘机输出配置文件) |------userdef_stamp_formats (奥宝LDI输出自动参数配置文件) |------rout_tools (锣带刀具参数配置文件) |------script_start.csh (脚本运行起始程序) |---scripts (脚本存放目录) |---bindings (脚本快捷键绑定文件) |---colors (图层颜色配置文件) |---dblist (料号库配置文件) |tmp (临时文件存储目录) |Xmanager(Xmanager软件目录,Windows平台必须依赖此软件才能执行Genesis2000) |Genesis.bat (软件启动批处理文件)
-
-
2.InCAM/InCAMPro的主要系统参数及管理目录说明:
-
InCAM/InCAMPro软件目录图示

-
系统结构及主要文件程式释义:
|tmp (临时文件存储目录) |release (软件版本主程序) |---app_data |------errs |---------ALL_ERRS (软件所有报错弹窗信息分类汇总文档) |------img (软件图片资源目录) |------markers (分孔图样式文件存放目录,允许自定义分孔图刀序样式) |------perl (perl语言接口存放位置,我们可以参照这些接口自定义其他开发语言的接口) |------python (python语言接口存放位置,新版本的InCAMPro中已提供官方版本的python接口) |------sysattr (系统属性文件,我们一般不在这里自定义属性,因为这个文件会跟随版本一起升级) |---bin |------admin_tools (系统管理软件目录) |------inlink (inlink安装路径) |------incampro.csh (InCAMPro启动脚本) |------dbutil (dbutil程式) |------gateway (gateway程式,外挂实现的主程式) |------incamd (InCAMPro主服务程式) |---def_data (软件的一些默认配置文件及系统路径) |---help (帮助文档存放目录) |---incamgv (料号web浏览主程序,需要单独的license) |---utils (存放一些系统的依赖包或者一些常用的系统程式) |incamd (软件主服务程序目录) |---app_data |---bin |---utils |server (软件配置服务目录) |---config (一些诶主要的配置文件及license文件存放路径) |------license (存放授权文件目录) |------groups.xml (用户组配置文件) |------joblist.xml (料号清单文件) |------privs (权组配置文件) |------rcs (料号上锁清单文件) |------users.xml (用户账户/明码配置文件) |---logs (存放日志文件) |---site_data (系统配置及脚本主目录) |------frontline_prog (erf参数文档主目录,当前路径下有frontline_prog时软件默认优先读此路径) |---------dfm (软件优化功能配置文件目录) |---------cleanup(软件cleanup配置文件目录) |---------analysis (软件分析功能配置文件目录) |------hooks (软件钩子脚本目录汇总) |---------ffilters (软件过滤器脚本配置目录) |------------names (过滤器功能清单) |------------script 过滤器功能配置脚本) |---------line_hooks (软件lmc指令钩子脚本目录) |------------指令.pre (指令前置钩子脚本, 执行指令前先做什么) |------------指令.post (指令后置钩子脚本, 执行指令后再做什么) |---------ncd (自动钻孔输出管理器钩子脚本及配置文件路径) |---------ncr (自动锣带输出管理器钩子脚本及配置文件路径) |---------acquire (自动备份导入配置脚本,较少使用) |---------secure (自动备份导出配置脚本,较少使用) |---------drill_size (自动补偿钻孔管理器钩子脚本) |---------drill_size.tab (钻头配置文件) |---------film_sizes (奥宝光绘机底片尺寸配置文件) |---------lyr_rule (按厂内层别命名自动定义属性及排序配置文件) |---------orbotech_plot_spool.config (奥宝光绘机输出配置文件) |---------userdef_stamp_formats (奥宝LDI输出自动参数配置文件) |---------rout_tools (锣带刀具参数配置文件) |---------script_start.csh (脚本运行起始程序) |------scripts (脚本存放目录) |---library |------cam_guides (camguide文件主目录) |------chk (用户自定义参数主目录) |------fonts (字体存放目录, 优先读取库中的字体) |------fonts_ex (自定义的cad字体存放目录, 优先读取库中的字体) |------forms (存放所有forms文件,已过时) |------symbols (系统symbol库) |------whltemps (wheel库) |---users (用户目录) |---init.csh (环境变量配置脚本) |---init.gen (环境变量配置脚本) |idb (软件料号库,路径可以自定义) |---jobs (料号资料目录) |CamConnector (InPlan/Inflow同步服务程序目录) |tnsnames.ora (Inlink TNS配置文件) |network_config.xml (server目录及tmp临时目录指向配置文档)
-
-
以上只是列举的部分维护过程中必须了解的系统路径及文件,在InCAMPro的维护中基本上已实现了通过软件界面或者管理员工具实现了前台管理,在非必要的情况下我们尽量不去修改后台文件来维护系统!
第16课.Genesis2000/InCAM/InCAMPro基础命令
-
1.Genesis2000的开发文档路径"你的安装路径\e100\all\helps\line":
在此我们主要是学会看懂开发文件的的指令释义
我们以最常见的add_pad为例:
首先找到开发文档路径下的editor文件,用写字板打开并找到"add_pad",如下图:

释义:
Command: add_pad ------>指令:添加pad
Description: 描述----------->描述: 为受影响的层别添加pad功能…
Parameter: 参数------------>指令有哪些参数:- attributes : yes/no----------> 是否为添加的pad添加属性,"yes"是,"no"否;
- x, y: 添加的坐标哪里,x->x方向坐标值,y->y方向坐标值;
- symbol: 添加的物件名字,在Genesis2000中symbol是某个物件的统称;
- polarity:添加symbol的极性,"positive"正极性,"negative"负极性;
- angle:添加的symbol角度;
- mirror:是否镜像添加,"yes"是,"no"否;
- nx:x方向添加的个数;
- ny:y方向添加的个数;
- dx:x方向添加的间距;
- dy:y方向添加的间距;
- xscale:x方向的涨缩比例值;
- yscale:y方向的涨缩比例值
- 那么我们添加一个pad的完整指令就是:
add_pad,attributes=no,x=0,y=0,symbol=r100,polarity=positive,angle=0,mirror=no,nx=1,ny=1,dx=0,dy=0,xscale=1,yscale=1
释义:在0,0坐标处添加一个大小为100的圆pad,极性为正,角度为0度,不镜像,x,y方向只有一个,x,y方向的间距为零,涨缩系数x,y为1:1不涨缩
软件中添加效果:

如图,我们在软件界面的操作实际上就是再执行一条条的软件内置指令,脚本实际上就是让软件按照我们编制好的指令集有逻辑有计划的执行软件的内置指令,到这里我们就要理解了,不是用户做不到写个脚本就好了,能写脚本的前提是软件支持我们需要的指令或者指令集,与软件开发不是在一个维度的工作,我们称为软件二次开发或者脚本开发,与软件开发不同的是,一个是软件功能或者指令从无到有的过程,一个是在现有的指令或者指令集基础上开发出用户便捷高效且客制化的功能,理解到这一点大家就应该能对我们现在的脚本工作有个基本的了解了!
-
2.InCAM/InCAMPro从本质上来说它就是Genesis2000的升级版本,所以我们学习理解这两款软件如果是建立在已经掌握Genesis2000/GenFlex的基础上会相当容易上手,以我个人经验来说完全不会有任何难度,最大的不适应仅仅是初期操作习惯养成问题而已,以相同的add_pad指令为例,我们看看操作和开发文档有多大差异:
- 首先我们打开开发文档,如下图直接在软件界面即可开启:

- 我们在看看InCAM/InCAMPro的指令:

如图此条指令在InCAMPro中与Genesis2000的指令并无太大的差异,仅仅是新增了"direction",“resize"这两个参数,具体的释义不做复述,这就是为什么我们的Genesis2000脚本代码为什么能直接在InCAM/InCAMPro上直接运行的原因,因为它们的底层指令是差不多的,当然反过来也就是为什么Genesis2000很多时候不能运行InCAM/InCAMPro代码的原因了,总结下来就是一句话"向下兼容,高版本兼容低版本”,我们再看看用户操作,如下图:

如上图,对于用户操作基本大同小异,对于已经掌握Genesis2000操作的人员并不会有太高的学习成本,对于脚本工程师更是没有任何难度可言!
综上所述,我们开发脚本时,最重要的是了解软件的功能,熟练掌握基础开发指令,很多同行可能会有个疑问,软件是自带基础指令录制功能的,我们直接使用录制的代码修改不一样的可以完成脚本编辑,这里要特别强调,录制的代码并不是包含所有指令参数的,部分指令也是不支持录制的,所以,看官方提供的文档永远是最准确可靠的!
- 首先我们打开开发文档,如下图直接在软件界面即可开启:
第四章.系统维护学习
第17课.Linux系统维护汇总(PCB制造业制前工程CAM系统相关)
CentOS7系统维护汇总
-
操作系统相关:
-
1.配置CentOS7国内镜像源
打开终端,备份原有源文件:mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup下载阿里云镜像源(适用于CentOS 7):
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo清理缓存并生成新缓存:
yum clean all && yum makecache -
2.安装必要的工具包
以下为常用工具包安装命令:yum install -y epel-release # 安装EPEL扩展源 yum install -y vim wget curl net-tools lsof telnet zip unzip yum groupinstall -y "Development Tools" # 开发工具组 -
3.系统时间同步异常
检查并启用NTP服务:yum install -y ntp systemctl start ntpd systemctl enable ntpd timedatectl set-timezone Asia/Shanghai # 设置时区 -
4.防火墙与SELinux配置
临时关闭防火墙(生产环境慎用):systemctl stop firewalld systemctl disable firewalld临时禁用SELinux:
setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config -
5.磁盘空间不足处理
查看磁盘使用情况:df -h清理旧内核及日志文件:
yum autoremove # 移除旧内核 journalctl --vacuum-size=50M # 限制日志大小 -
6.SSH连接超时问题
修改/etc/ssh/sshd_config,调整以下参数:ClientAliveInterval 60 ClientAliveCountMax 3重启SSH服务生效:
systemctl restart sshd -
7.网络接口启动失败
检查网卡配置文件(如ifcfg-eth0):vi /etc/sysconfig/network-scripts/ifcfg-eth0确保
ONBOOT=yes,重启网络服务:systemctl restart network -
8.系统语言乱码问题
安装中文语言包并设置环境:yum install -y glibc-common zh-CN localectl set-locale LANG=zh_CN.UTF-8 -
9.Yum安装报错“Could not resolve host”
检查DNS配置:vi /etc/resolv.conf添加可靠DNS服务器(如
nameserver 8.8.8.8),重启网络服务。 -
10.内核参数优化
修改/etc/sysctl.conf,追加以下内容:net.ipv4.tcp_fin_timeout = 30 fs.file-max = 65535使配置生效:
sysctl -p -
11.配置自定义的系统服务(自定义启动程序以名为askpcbvnc的程式为例)
1.编写自动执行脚本askpcbvnc.sh:#!/bin/sh export ASK_PCB_VNC_DIR=/home/incam # 设置程式安装目录环境变量 export LANG=en_US.UTF-8 # 设置语言环境 export LC_ALL=en_US.UTF-8 # 覆盖所有其他区域设置变量 case "$1" in 'start') if [ -x $ASK_PCB_VNC_DIR ]; then cd $ASK_PCB_VNC_DIR echo '启动askpcbvnc服务中...' for i in {10..30}; do ./askpro5new $i & done wait fi ;; 'stop') echo '终止askpcbvnc服务中...' pkill -f askpro5new ps -ef | grep 'Xvnc -depth 24' | grep -v grep | awk '{print $2}' | xargs kill -9 ;; 'restart') $0 stop $0 start ;; 'status') if pgrep -f askpcbvnc.sh > /dev/null; then echo "askpcbvnc服务正在运行中." else echo "askpcbvnc服务异常." fi ;; *) echo "例句: /etc/init.d/askpcbvnc {start|stop|restart|status}" exit 1 ;; esac exit 0
2.保存脚本文件到"/etc/init.d"目录并赋予执行权限:
cd /etc/init.d chmod +x askpcbvnc.sh注意事项:
1.代码主要调用askpro5new可执行文件,文件路径:/home/incam/askpro5new
3.创建systemd服务文件(/etc/systemd/system/askpcbvnc.service):
直接在root用户终端执行以下指令vim /etc/systemd/system/askpcbvnc.service将以下代码写入"/etc/systemd/system/askpcbvnc.service"文件并保存
[Unit] Description=Ask PCB VNC Service After=network.target [Service] # User=incam Environment="HOME=/home/incam" Type=simple ExecStart=/bin/sh /etc/init.d/askpcbvnc.sh start ExecStop=/bin/sh /etc/init.d/askpcbvnc.sh stop User=incam Group=incam WorkingDirectory=/home/incam Restart=on-failure [Install] WantedBy=multi-user.target
4.配置Centos7系统服务askpcbvnc.service
启用服务
运行以下命令以启用并启动服务:# 重新加载 systemd 管理器配置 sudo systemctl daemon-reload # 启动服务 sudo systemctl start askpcbvnc.service # 设置开机自启 sudo systemctl enable askpcbvnc.service
5.管理服务
- 查看状态:
systemctl status askpcbvnc.service - 停止服务:
systemctl stop askpcbvnc.service - 重启服务:
systemctl restart askpcbvnc.service
- 查看状态:
-
12.直接禁用 usb0 且不影响其他 USB 设备的简明方案
直接禁用 usb0 且不影响其他 USB 设备的简明方案:bash复制# 1. 立即禁用接口 sudo ip link set dev usb0 down # 2. 阻止接口自动启动 sudo tee /etc/sysconfig/network-scripts/ifcfg-usb0 >/dev/null <<'EOF' DEVICE=usb0 ONBOOT=no NM_CONTROLLED=no EOF # 3. 创建强效 UDEV 规则(匹配物理设备特征) USB_VENDOR=$(cat /sys/class/net/usb0/device/idVendor 2>/dev/null) USB_PRODUCT=$(cat /sys/class/net/usb0/device/idProduct 2>/dev/null) sudo tee /etc/udev/rules.d/99-kill-usb0.rules >/dev/null <<EOF # 物理级禁用USB网卡 ACTION=="add", SUBSYSTEM=="usb", ENV{ID_VENDOR_ID}=="$USB_VENDOR", ENV{ID_MODEL_ID}=="$USB_PRODUCT", RUN+="/bin/sh -c 'echo 1 > /sys\$DEVPATH/remove'" EOF # 4. 立即触发规则 sudo udevadm control --reload-rules sudo udevadm trigger sleep 2 # 等待规则执行 # 5. 物理移除设备(模拟拔插) echo "1" | sudo tee /sys/bus/usb/devices/*/remove >/dev/null 2>&1最终验证命令:
bash复制# 检查接口状态(应不存在) ip link show usb0 2>&1 | grep "not exist" # 检查设备连接(无输出表示成功) lsusb | grep "$USB_VENDOR:$USB_PRODUCT"永久禁用原理:
组件 作用 效果 ip link set down 立即关闭接口 临时停止网络通信 ifcfg-usb0(配置文件) 禁止系统启动 防止重启后自动启用 UDEV 物理移除规则 拦截设备注册 阻止内核识别设备 sysfs remove(操作) 模拟设备拔除 强制断开物理连接 恢复方法:
bash复制sudo rm -f /etc/sysconfig/network-scripts/ifcfg-usb0 sudo rm -f /etc/udev/rules.d/99-kill-usb0.rules sudo udevadm control --reload-rules # 重新连接物理设备或重启系统 -
13.CentOS 7保留最新2个版本内核
# root用户下 package-cleanup --oldkernels --count=2
-
-
CAM软件系统相关:
-
1.Centos7下的InCAMPro导出odb++需安装依赖包
经验分享:解决InCAMPro导出odb++卡死的问题
yum install -y glibc.i686 yum install -y libSM-1.2.1-7.el7.i686.rpm yum install -y libXext-1.3.2-2.1.el7.i686.rpm yum install -y zlib-1.2.7-13.el7.i686.rpm yum install -y freetype-2.4.11-9.el7.i686.rpm yum install -y libstdc++-4.8.3-9.el7.i686.rpm yum install -y libpng12-1.2.50-6.el7.i686.rpm yum install -y libXrender-0.9.8-2.1.el7.i686.rpm yum install -y libxft.i686 yum install -y dos2unix yum install -y tcsh-6.20.00-12.el8.x86 64.rpm yum install -y libXaw-1.0.13-10.el8.x86 64.rpm yum install -y libxcrypt-4.1.1-4.el8.i686.rpm -
2.远程保存
经验分享:解决Genesis2000/InCAM/InCAMPro远程保存的问题
首先了解什么是PID:PID字面理解就是唯一进程码的意思,每开启一个软件窗口系统都会产生一个唯一的进程码,在Genesis2000/InCAM/InCAMPro中,界面直接可以看到进程码,如下图:

# 1.执行"/incam/incamd/bin/gateway WHO"获取用户地址 [incam@incampro-yy-server ~/Desktop]$ /incam/incamd/bin/gateway WHO a1@incampro-yy-server.incampro-yy-server:90 lyk@incampro-yy-server.incampro-yy-server:90 jwz@incampro-yy-server.incampro-yy-server:90 # 释义: 主机incampro-yy-server 5990端口登录了三个InCAMPro账号(a1, lyk, jwz) # 2.执行"/incam/incamd/bin/gateway lyk@incampro-yy-server.incampro-yy-server:90 'COM save_job,job=me10n99519a0,override=no'"料号保存指令 /incam/incamd/bin/gateway lyk@incampro-yy-server.incampro-yy-server:90 'COM save_job,job=me10n99519a0,override=no' # 释义: 使用gateway工具远程保存lyk用户正在操作的me10n99519a0料号 # 3.执行"/incam/incamd/bin/gateway %PID@incampro-yy-server.incampro-yy-server 'COM script_run,name=/incam/server/site_data/scripts/CAM_output_system/MDM_data_output/get_mdm_info-t.py,env1=JOB=m06a0786a00,env2=STEP=panel,params=1'"运行脚本 /incam/incamd/bin/gateway %PID(假设编码为123)@incampro-yy-server.incampro-yy-server:90 'COM script_run,name=/incam/server/site_data/scripts/CAM_output_system/MDM_data_output/get_mdm_info-t.py,env1=JOB=m06a0786a00,env2=STEP=panel,params=1' # 释义: 使用gateway工具远程在incampro-yy-server主机的5992端口调用PID为123的InCAMPro软件运行脚本/incam/server/site_data/scripts/CAM_output_system/MDM_data_output/get_mdm_info-t.py,env1=JOB=m06a0786a00,env2=STEP=panel,params=1 -
3.批量杀进程(以InCAMPro为例)
经验分享:解决类似InCAMPro软件批量退出的问题
# 搜索所有的InCAMPro进程并获取进程号后批量终止 ps -e | grep InCAMPro | awk '{print $1}' | xargs kill -9 -
4.系统网络不稳定监测(当使用服务器版软件时会影响软件运行)
经验分享:监测网络对软件运行的影响
# 监测并存储网络丢包数据 ping incampro-yy-server| awk '{print $0"\t" strftime("%Y-%m-%d %H:%M:%S", systime()); fflush()}' >> /home/incam/桌面/test.txt # 释义: ping 主机incampro-yy-server 同时将监测的数据存储到指定路径以便后续数据分析或者留存证据 -
5.清除InCAMPro产生的大量日志数据
经验分享: CAM软件运行过程中会自动产生大量的日志数据,当我们不需要的时候应该及时清理
# 清除指定的临时文件 # 案例1: cd /incam/tmp find ../statistics -mtime +60 -name "statistics-*" -exec rm -Rf {} ; # 释义: 删除指定时间前的文件(以删除60天前当前路径statistics目录statistics-开头的文件) # 案例2: find ./ -maxdepth 1 -type f -newermt "Jan 13" -delete # 释义: 删除当前文件夹下指定时间(Jan 13)的文件
-
-
系统磁盘空间容量异常(案例):
参考博文:Centos7下用Python写一个磁盘空间自动预警脚本
第五章.脚本开发学习
第18课.Python3基础
-
Python简介
Python是一种高级、解释型的编程语言,以简洁易读的语法著称。- 特点
- 简单易学
- 开源免费
- 跨平台
- 丰富的库支持
- 特点
-
环境搭建
- 安装Python
# Windows 下载官网安装包:https://www.python.org/downloads/ # Mac brew install python # Linux(CentOS 7) sudo yum install python3 -y
- 安装Python
-
开发工具推荐
- VS Code
- PyCharm
- Jupyter Notebook
-
基础语法
第一个Python程序print("Hello, World!")- 变量和数据类型
# 基本数据类型 name = "Python" # 字符串 age = 30 # 整数 price = 19.99 # 浮点数 is_active = True # 布尔值 print(f"语言: {name}, 年龄: {age}年") - 运算符
# 算术运算符 a = 10 b = 3 print(a + b) # 13 print(a - b) # 7 print(a * b) # 30 print(a / b) # 3.333... print(a // b) # 3 (整除) print(a % b) # 1 (取余)
- 变量和数据类型
-
数据结构
-
列表(List)
# 创建列表 fruits = ['apple', 'banana', 'orange'] numbers = [1, 2, 3, 4, 5] # 列表操作 fruits.append('grape') # 添加元素 fruits.remove('banana') # 删除元素 print(fruits[0]) # 访问元素 print(len(fruits)) # 列表长度 -
字典(Dictionary)
# 创建字典 person = { 'name': 'Alice', 'age': 25, 'city': 'Beijing' } # 字典操作 print(person['name']) # 访问值 person['job'] = 'Engineer' # 添加键值对 del person['age'] # 删除键值对 # 遍历字典 for key, value in person.items(): print(f"{key}: {value}") -
元组和集合
# 元组(不可变) coordinates = (10, 20) print(coordinates[0]) # 集合(不重复) unique_numbers = {1, 2, 3, 3, 4} print(unique_numbers) # {1, 2, 3, 4}
-
-
控制流程
- 条件语句
# if-elif-else score = 85 if score >= 90: grade = 'A' elif score >= 80: grade = 'B' elif score >= 70: grade = 'C' else: grade = 'D' print(f"分数: {score}, 等级: {grade}") - 循环语句
# for循环 for i in range(5): print(f"循环次数: {i}") # while循环 count = 0 while count < 3: print(f"计数: {count}") count += 1 # 列表推导式 squares = [x**2 for x in range(1, 6)] print(squares) # [1, 4, 9, 16, 25]
- 条件语句
-
函数编程
- 函数定义
def greet(name, message="Hello"): """打招呼的函数""" return f"{message}, {name}!" # 调用函数 result = greet("World") print(result) # 带返回值的函数 def calculate_area(length, width): """计算矩形面积""" return length * width area = calculate_area(5, 3) print(f"面积: {area}") - 高阶函数
# lambda表达式 square = lambda x: x ** 2 print(square(5)) # 25 # map函数 numbers = [1, 2, 3, 4, 5] squared = list(map(lambda x: x**2, numbers)) print(squared) # [1, 4, 9, 16, 25]
- 函数定义
-
面向对象编程
- 类和对象
class Dog: """狗类""" def __init__(self, name, breed): self.name = name self.breed = breed def bark(self): return f"{self.name}在汪汪叫!" def get_info(self): return f"名字: {self.name}, 品种: {self.breed}" # 创建对象 my_dog = Dog("旺财", "金毛") print(my_dog.bark()) print(my_dog.get_info()) - 继承和多态
class Animal: def __init__(self, name): self.name = name def speak(self): pass class Cat(Animal): def speak(self): return "喵喵喵" class Dog(Animal): def speak(self): return "汪汪汪" # 多态示例 animals = [Cat("咪咪"), Dog("小黑")] for animal in animals: print(f"{animal.name}: {animal.speak()}")
- 类和对象
-
文件操作
- 读写文件
# 写入文件 with open('example.txt', 'w', encoding='utf-8') as file: file.write("Hello, Python!\n") file.write("这是第二行内容") # 读取文件 with open('example.txt', 'r', encoding='utf-8') as file: content = file.read() print(content) # 逐行读取 with open('example.txt', 'r', encoding='utf-8') as file: for line in file: print(line.strip())
- 读写文件
-
异常处理
- try-except语句
try: num = int(input("请输入一个数字: ")) result = 10 / num print(f"结果是: {result}") except ValueError: print("输入的不是有效数字!") except ZeroDivisionError: print("不能除以零!") except Exception as e: print(f"发生错误: {e}") else: print("计算成功!") finally: print("程序执行完毕")
- try-except语句
-
模块和包
- 导入模块
# 导入标准库 import math import random from datetime import datetime # 使用模块 print(math.sqrt(16)) # 4.0 print(random.randint(1, 100)) # 创建自定义模块 # mymodule.py def say_hello(): return "Hello from my module!"
- 导入模块
-
高级特性
- 装饰器
def timer_decorator(func): def wrapper(*args, **kwargs): import time start = time.time() result = func(*args, **kwargs) end = time.time() print(f"函数 {func.__name__} 执行时间: {end - start:.2f}秒") return result return wrapper @timer_decorator def slow_function(): import time time.sleep(1) return "完成" slow_function() - 生成器
def fibonacci_generator(n): """生成斐波那契数列""" a, b = 0, 1 for _ in range(n): yield a a, b = b, a + b # 使用生成器 for num in fibonacci_generator(10): print(num, end=' ')
- 装饰器
-
项目实战
- 简易待办事项应用
class TodoList: def __init__(self): self.tasks = [] def add_task(self, task): self.tasks.append({"task": task, "completed": False}) print(f"添加任务: {task}") def complete_task(self, task_index): if 0 <= task_index < len(self.tasks): self.tasks[task_index]["completed"] = True print(f"完成任务: {self.tasks[task_index]['task']}") else: print("任务索引无效") def show_tasks(self): print("\n=== 待办事项 ===") for i, task in enumerate(self.tasks): status = "✓" if task["completed"] else "○" print(f"{i}. [{status}] {task['task']}") # 使用示例 todo = TodoList() todo.add_task("学习Python") todo.add_task("写项目") todo.show_tasks() todo.complete_task(0) todo.show_tasks() - 数据分析示例
import pandas as pd import numpy as np # 创建示例数据 data = { 'Name': ['Alice', 'Bob', 'Charlie', 'David'], 'Age': [25, 30, 35, 28], 'Salary': [50000, 60000, 70000, 55000] } df = pd.DataFrame(data) print("原始数据:") print(df) # 基本数据分析 print(f"\n数据形状: {df.shape}") print(f"\n描述性统计:") print(df.describe()) # 数据筛选 high_salary = df[df['Salary'] > 55000] print(f"\n高薪人员:") print(high_salary)
- 简易待办事项应用
-
总结
Python是一门功能强大且易于学习的编程语言,适用于Web开发、数据分析、人工智能等多个领域。- 学习建议
1. 多写代码,多练习
2. 阅读优秀的开源代码
3. 参与实际项目开发
4. 持续学习新特性 - 进阶方向
- Web开发:Django、Flask
- 数据分析:Pandas、NumPy
- 机器学习:Scikit-learn、TensorFlow
- 自动化脚本
- 学习建议
第19课.Python3进阶
- Python编程进阶
-
高级数据结构
命名元组
from collections import namedtuple # 定义命名元组 Point = namedtuple('Point', ['x', 'y']) p = Point(10, 20) print(p.x, p.y) # 10 20 # 支持所有元组操作 print(p[0]) # 10默认字典
# 自动初始化缺失的键 word_count = defaultdict(int) words = ['apple', 'banana', 'apple', 'orange'] for word in words: word_count[word] += 1 print(word_count) # {'apple': 2, 'banana': 1, 'orange': 1}计数器
from collections import Counter # 快速计数 data = ['red', 'blue', 'red', 'green', 'blue', 'blue'] counter = Counter(data) print(counter.most_common(2)) # [('blue', 3), ('red', 2)]双端队列
from collections import deque # 高效的双端操作 dq = deque([1, 2, 3]) dq.appendleft(0) # 左端添加 dq.append(4) # 右端添加 print(dq) # deque([0, 1, 2, 3, 4]) -
并发编程
多线程
import threading import time def worker(num): """工作线程函数""" print(f'线程 {num} 开始工作') time.sleep(2) print(f'线程 {num} 完成工作') # 创建并启动线程 threads = [] for i in range(3): t = threading.Thread(target=worker, args=(i,)) threads.append(t) t.start() # 等待所有线程完成 for t in threads: t.join()线程池
from concurrent.futures import ThreadPoolExecutor import requests def download_url(url): """下载URL内容""" response = requests.get(url) return f'{url}: {len(response.content)} bytes' urls = [ 'https://httpbin.org/get', 'https://httpbin.org/post', 'https://httpbin.org/put' ] # 使用线程池执行 with ThreadPoolExecutor(max_workers=3) as executor: results = executor.map(download_url, urls) for result in results: print(result)多进程
import multiprocessing import os def square_number(n): """计算数字的平方""" print(f'进程 {os.getpid()} 计算 {n} 的平方') return n * n if __name__ == '__main__': numbers = [1, 2, 3, 4, 5] # 使用进程池 with multiprocessing.Pool(processes=2) as pool: results = pool.map(square_number, numbers) print(f'结果: {results}') -
异步编程
异步函数
import asyncio import aiohttp async def fetch_url(session, url): """异步获取URL""" async with session.get(url) as response: return await response.text() async def main(): """主异步函数""" async with aiohttp.ClientSession() as session: tasks = [ fetch_url(session, 'https://httpbin.org/get'), fetch_url(session, 'https://httpbin.org/post') ] results = await asyncio.gather(*tasks) for result in results: print(f'获取到 {len(result)} 字符') # 运行异步程序 asyncio.run(main())异步生成器
import asyncio async def async_counter(limit): """异步计数器""" for i in range(limit): yield i await asyncio.sleep(0.1) async def main(): async for number in async_counter(5): print(f'当前数字: {number}') asyncio.run(main()) -
元编程
装饰器进阶from functools import wraps import time def retry(max_attempts=3, delay=1): """重试装饰器""" def decorator(func): @wraps(func) def wrapper(*args, **kwargs): for attempt in range(max_attempts): try: return func(*args, **kwargs) except Exception as e: if attempt == max_attempts - 1: raise e print(f'第 {attempt + 1} 次尝试失败,{delay}秒后重试') time.sleep(delay) return None return wrapper return decorator @retry(max_attempts=3, delay=2) def unreliable_function(): """不可靠的函数""" import random if random.random() < 0.7: raise ValueError('随机失败') return '成功' print(unreliable_function())元类
class SingletonMeta(type): """单例元类""" _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super().__call__(*args, **kwargs) return cls._instances[cls] class DatabaseConnection(metaclass=SingletonMeta): """数据库连接类""" def __init__(self, connection_string): self.connection_string = connection_string print(f'创建数据库连接: {connection_string}') # 测试单例 conn1 = DatabaseConnection('mysql://localhost:3306') conn2 = DatabaseConnection('mysql://localhost:3306') print(conn1 is conn2) # True描述符
class PositiveNumber: """正数描述符""" def __set_name__(self, owner, name): self.name = name def __get__(self, instance, owner): return instance.__dict__.get(self.name) def __set__(self, instance, value): if value <= 0: raise ValueError('必须是正数') instance.__dict__[self.name] = value class Product: price = PositiveNumber() quantity = PositiveNumber() def __init__(self, price, quantity): self.price = price self.quantity = quantity # 使用描述符 try: product = Product(-10, 5) except ValueError as e: print(f'错误: {e}') -
性能优化
内存分析import sys import tracemalloc def process_data(): """处理数据的函数""" data = [i**2 for i in range(10000)] return sum(data) # 跟踪内存使用 tracemalloc.start() result = process_data() snapshot = tracemalloc.take_snapshot() tracemalloc.stop() # 显示内存使用情况 for stat in snapshot.statistics('lineno')[:5]: print(stat)性能分析
import cProfile import pstats def slow_function(): """慢速函数""" total = 0 for i in range(100000): total += i return total # 性能分析 profiler = cProfile.Profile() profiler.enable() result = slow_function() profiler.disable() stats = pstats.Stats(profiler) stats.sort_stats('cumulative') stats.print_stats(10)缓存优化
from functools import lru_cache @lru_cache(maxsize=128) def fibonacci(n): """带缓存的斐波那契函数""" if n < 2: return n return fibonacci(n-1) + fibonacci(n-2) # 测试缓存效果 import time start = time.time() result = fibonacci(35) end = time.time() print(f'斐波那契(35) = {result}, 耗时: {end-start:.2f}秒') -
设计模式
工厂模式from abc import ABC, abstractmethod class Animal(ABC): """动物抽象类""" @abstractmethod def speak(self): pass class Dog(Animal): def speak(self): return "汪汪汪" class Cat(Animal): def speak(self): return "喵喵喵" class AnimalFactory: """动物工厂""" @staticmethod def create_animal(animal_type): if animal_type == 'dog': return Dog() elif animal_type == 'cat': return Cat() else: raise ValueError(f'未知动物类型: {animal_type}') # 使用工厂 dog = AnimalFactory.create_animal('dog') cat = AnimalFactory.create_animal('cat') print(dog.speak(), cat.speak())观察者模式
class Subject: """主题类""" def __init__(self): self._observers = [] def attach(self, observer): self._observers.append(observer) def detach(self, observer): self._observers.remove(observer) def notify(self, message): for observer in self._observers: observer.update(message) class Observer: """观察者类""" def update(self, message): print(f'收到消息: {message}') # 使用观察者模式 subject = Subject() observer1 = Observer() observer2 = Observer() subject.attach(observer1) subject.attach(observer2) subject.notify('状态已更新')策略模式
from abc import ABC, abstractmethod class PaymentStrategy(ABC): """支付策略接口""" @abstractmethod def pay(self, amount): pass class CreditCardPayment(PaymentStrategy): def pay(self, amount): return f'信用卡支付 {amount} 元' class AlipayPayment(PaymentStrategy): def pay(self, amount): return f'支付宝支付 {amount} 元 class PaymentContext: """支付上下文""" def __init__(self, strategy: PaymentStrategy): self._strategy = strategy def execute_payment(self, amount): return self._strategy.pay(amount) # 使用策略模式 credit_payment = PaymentContext(CreditCardPayment()) alipay_payment = PaymentContext(AlipayPayment()) print(credit_payment.execute_payment(100)) print(alipay_payment.execute_payment(200)) -
网络编程
Socket编程import socket def start_server(): """启动服务器""" server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 8888)) server_socket.listen(1) print('服务器启动,等待连接...') client_socket, addr = server_socket.accept() print(f'客户端连接来自: {addr}') # 接收数据 data = client_socket.recv(1024) print(f'收到数据: {data.decode()}') # 发送响应 client_socket.send(b'Hello from server!') client_socket.close() server_socket.close() def start_client(): """启动客户端""" client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('localhost', 8888)) client_socket.send(b'Hello from client!') response = client_socket.recv(1024) print(f'服务器响应: {response.decode()}') client_socket.close() # 在实际应用中,服务器和客户端应该在不同的进程中运行HTTP客户端
import requests import json class APIClient: """API客户端""" def __init__(self, base_url): self.base_url = base_url def get(self, endpoint, params=None): """GET请求""" response = requests.get(f'{self.base_url}/{endpoint}', params=params) return response.json() def post(self, endpoint, data=None): """POST请求""" headers = {'Content-Type': 'application/json'} response = requests.post( f'{self.base_url}/{endpoint}', data=json.dumps(data), headers=headers ) return response.json() # 使用API客户端 client = APIClient('https://jsonplaceholder.typicode.com') posts = client.get('posts') print(f'获取到 {len(posts)} 篇文章') -
数据库操作
SQLite操作import sqlite3 from contextlib import contextmanager @contextmanager def get_db_connection(): """获取数据库连接""" conn = sqlite3.connect('example.db') try: yield conn finally: conn.close() def setup_database(): """设置数据库""" with get_db_connection() as conn: cursor = conn.cursor() # 创建表 cursor.execute(''' CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT UNIQUE NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ''') # 插入数据 cursor.execute( 'INSERT INTO users (name, email) VALUES (?, ?)', ('Alice', 'alice@example.com') ) conn.commit() def query_users(): """查询用户""" with get_db_connection() as conn: cursor = conn.cursor() cursor.execute('SELECT * FROM users') users = cursor.fetchall() return users # 使用数据库 setup_database() users = query_users() print(f'用户列表: {users}')ORM使用
from sqlalchemy import create_engine, Column, Integer, String, DateTime from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from datetime import datetime Base = declarative_base() class User(Base): """用户模型""" __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String(50), nullable=False) email = Column(String(100), unique=True, nullable=False) created_at = Column(DateTime, default=datetime.now) # 设置数据库连接 engine = create_engine('sqlite:///advanced.db') Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) def add_user(name, email): """添加用户""" session = Session() try: user = User(name=name, email=email) session.add(user) session.commit() return user except Exception as e: session.rollback() raise e finally: session.close() # 使用ORM user = add_user('Bob', 'bob@example.com') print(f'添加用户: {user.name}') -
测试与调试
单元测试import unittest def add_numbers(a, b): """相加函数""" return a + b class TestMathFunctions(unittest.TestCase): """数学函数测试""" def test_add_positive_numbers(self): self.assertEqual(add_numbers(2, 3), 5) def test_add_negative_numbers(self): self.assertEqual(add_numbers(-2, -3), -5) def test_add_mixed_numbers(self): self.assertEqual(add_numbers(5, -3), 2) class TestStringMethods(unittest.TestCase): """字符串方法测试""" def test_upper(self): self.assertEqual('hello'.upper(), 'HELLO') def test_isupper(self): self.assertTrue('HELLO'.isupper()) self.assertFalse('Hello'.isupper()) if __name__ == '__main__': unittest.main()模拟测试
from unittest.mock import Mock, patch import unittest class WeatherService: """天气服务""" def get_temperature(self, city): # 模拟网络请求 raise ConnectionError('网络连接失败') class TestWeatherService(unittest.TestCase): """天气服务测试""" @patch('requests.get') def test_get_weather(self, mock_get): # 设置模拟返回值 mock_response = Mock() mock_response.json.return_value = {'temperature': 25} mock_get.return_value = mock_response # 测试函数 def get_weather(): import requests response = requests.get('https://api.weather.com') return response.json() def test_mock_object(self): # 创建模拟对象 mock_obj = Mock() mock_obj.some_method.return_value = 42 result = mock_obj.some_method() self.assertEqual(result, 42) -
部署与打包
虚拟环境管理
# 创建虚拟环境 python -m venv myenv # 激活虚拟环境 # Windows myenv\Scripts\activate # Linux/Mac source myenv/bin/activate # 安装依赖 pip install -r requirements.txt # 冻结依赖 pip freeze > requirements.txt应用打包
# setup.py 文件示例 from setuptools import setup, find_packages setup( name='my_python_app', version='1.0.0', packages=find_packages(), install_requires=[ 'requests>=2.25.1', 'sqlalchemy>=1.4.0', ], entry_points={ 'console_scripts': [ 'myapp=my_package.main:main' ] }, classifiers=[ 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'Programming Language :: Python :: 3', ], )Docker部署
# Dockerfile 示例 FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD ["python", "main.py"] -
最佳实践
代码组织
# 项目结构建议 """ my_project/ ├── src/ │ ├── __init__.py │ ├── main.py │ ├── models/ │ ├── services/ │ └── utils/ ├── tests/ ├── docs/ ├── requirements.txt ├── setup.py └── README.md """ ### 配置管理 import os from dataclasses import dataclass @dataclass class DatabaseConfig: """数据库配置""" host: str = os.getenv('DB_HOST', 'localhost') port: int = int(os.getenv('DB_PORT', '5432')) database: str = os.getenv('DB_NAME', 'myapp')) username: str = os.getenv('DB_USER', 'postgres')) password: str = os.getenv('DB_PASS', 'password')) @dataclass class AppConfig: """应用配置""" debug: bool = os.getenv('DEBUG', 'False').lower() == 'true' # 使用配置 db_config = DatabaseConfig() app_config = AppConfig()日志管理
import logging import logging.config def setup_logging(): """设置日志配置""" logging.config.dictConfig({ 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s' }, 'handlers': { 'file': { 'class': 'logging.FileHandler', 'filename': 'app.log', 'formatter': 'standard' }, 'loggers': { '': { 'handlers': ['file'], 'level': 'INFO', 'propagate': True } } }) # 使用日志 logger = logging.getLogger(__name__) logger.info('应用程序启动') logger.error('发生错误')本进阶教程涵盖了Python编程的高级主题,包括并发编程、异步处理、元编程、性能优化等关键领域。通过掌握这些知识,你将能够编写更高效、更健壮的Python应用程序
-
第20课.Python3高阶
- Python编程高阶
- 深入Python数据模型与魔法协议
-
魔法方法的进阶应用
Python数据模型的核心在于理解魔法方法如何与语言结构交互。__getattribute__和 __getattr__的区别至关重要:前者在每次属性访问时都会调用,后者仅在属性不存在时调用。class ControlledAccess: def __init__(self): self._data = {} self.access_count = 0 def __getattribute__(self, name): # 统计所有属性访问,包括access_count自身 if name == "access_count": return object.__getattribute__(self, name) self.access_count += 1 return object.__getattribute__(self, name) def __getattr__(self, name): """只有正常属性查找失败时才调用""" print(f"创建新属性 {name}") self._data[name] = None return None obj = ControlledAccess() print(obj.access_count) # 0 print(obj.some_value) # 创建新属性 some_value print(obj.access_count) # 2 (统计了两次访问)上下文管理器的异步支持是Python高级特性的重要体现:
import asyncio from contextlib import asynccontextmanager class AsyncDatabaseConnection: async def __aenter__(self): await self.connect() return self async def __aexit__(self, exc_type, exc_val, exc_tb): await self.close() async def connect(self): print("建立数据库连接...") await asyncio.sleep(0.1) async def close(self): print("关闭数据库连接...") await asyncio.sleep(0.1) # 异步上下文管理器使用 async def main(): async with AsyncDatabaseConnection() as db: print("执行数据库操作") asyncio.run(main()) -
描述符协议的威力
描述符是属性访问的底层机制,理解它们对元编程至关重要。以下是类型验证描述符的进阶实现:from abc import ABC, abstractmethod from typing import Type, Any, Union class ValidatedDescriptor: def __init__(self, expected_type: Union[Type, tuple] = None, validator: callable = None): self.expected_type = expected_type self.validator = validator self.private_name = None def __set_name__(self, owner, name): self.private_name = f"_{name}" def __get__(self, instance, owner): if instance is None: return self return getattr(instance, self.private_name, None) def __set__(self, instance, value): if self.expected_type and not isinstance(value, self.expected_type): raise TypeError(f"期望类型 {self.expected_type}, 但得到 {type(value)}") if self.validator and not self.validator(value): raise ValueError(f"值 {value} 验证失败") setattr(instance, self.private_name, value) class PositiveNumber(ValidatedDescriptor): def __init__(self): super().__init__( expected_type=(int, float), validator=lambda x: x > 0 ) class BusinessModel: revenue = PositiveNumber() profit = PositiveNumber() def __init__(self, revenue, profit): self.revenue = revenue # 自动验证 self.profit = profit # 测试描述符 try: biz = BusinessModel(1000, -500) # 触发验证错误 except ValueError as e: print(f"业务验证失败: {e}")
- 元编程深度应用
- 元类的高级模式
元类不仅控制类的创建,还能实现强大的API设计模式。以下是声明式API的元类实现:class RegistryMeta(type): """注册表元类,自动注册所有子类""" _registry = {} def __new__(cls, name, bases, attrs): new_class = super().__new__(cls, name, bases, attrs) # 跳过基类 if bases != (object,) and bases != (): cls._registry[name] = new_class # 自动添加类名到注册表 if 'name' not in attrs: new_class.name = name.lower() return new_class def get_registry(cls): return cls._registry.copy() class Plugin(metaclass=RegistryMeta): pass class AuthPlugin(Plugin): description = "认证插件" class StoragePlugin(Plugin): description = "存储插件" print(RegistryMeta.get_registry()) # 自动注册所有插件 - 类装饰器的元编程应用
类装饰器可以修改或增强类的行为,是实现切面编程的强大工具:def singleton(cls): """单例类装饰器""" instances = {} def get_instance(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return get_instance def auto_register(registry_dict): """自动注册装饰器工厂""" def decorator(cls): registry_dict[cls.__name__] = cls return cls return decorator # 使用类装饰器 service_registry = {} @auto_register(service_registry) @singleton class DatabaseService: def __init__(self, connection_string): self.connection_string = connection_string @auto_register(service_registry) @singleton class CacheService: def __init__(self, max_size=1000): self.max_size = max_size print(service_registry) # 查看自动注册的服务
- 异步编程高级模式
- 异步上下文管理与资源池
异步编程的高级应用涉及复杂的资源管理和并发控制:import asyncio from contextlib import asynccontextmanager from typing import List, AsyncIterator class AsyncConnectionPool: def __init__(self, size: int = 5): self.size = size self._pool: List[str] = [] self._semaphore = asyncio.Semaphore(size) self._created = 0 async def _create_connection(self) -> str: """模拟异步创建连接""" await asyncio.sleep(0.1) conn_id = f"conn_{self._created}" self._created += 1 return conn_id @asynccontextmanager async def get_connection(self) -> AsyncIterator[str]: """异步上下文管理器获取连接""" await self._semaphore.acquire() try: if not self._pool: connection = await self._create_connection() else: connection = self._pool.pop() yield connection self._pool.append(connection) finally: self._semaphore.release() # 使用连接池 async def process_data(pool: AsyncConnectionPool, item: int): async with pool.get_connection() as conn: print(f"使用 {conn} 处理项目 {item}") await asyncio.sleep(0.2) return f"processed_{item}" async def main(): pool = AsyncConnectionPool(size=3) tasks = [process_data(pool, i) for i in range(10)] results = await asyncio.gather(*tasks) print(f"处理完成: {results}") # asyncio.run(main()) - 异步生成器与流处理
异步生成器是处理流式数据的强大工具:import asyncio import aiohttp from typing import AsyncIterator class AsyncDataStream: def __init__(self, urls: List[str], batch_size: int = 3): self.urls = urls self.batch_size = batch_size async def fetch_stream(self) -> AsyncIterator[str]: """异步获取数据流""" semaphore = asyncio.Semaphore(self.batch_size) async def fetch_with_limit(url: str) -> str: async with semaphore: async with aiohttp.ClientSession() as session: async with session.get(url) as response: data = await response.text() await asyncio.sleep(0.1) # 模拟处理延迟 return f"处理: {url} -> {len(data)} 字符" # 创建任务但按完成顺序产出 tasks = {asyncio.create_task(fetch_with_limit(url)): url for url in self.urls} while tasks: done, pending = await asyncio.wait( tasks.keys(), return_when=asyncio.FIRST_COMPLETED ) for task in done: url = tasks.pop(task) try: yield await task except Exception as e: yield f"错误 {url}: {e}"
- 并发模式与性能优化
-
高级线程池模式
对于I/O密集型应用,线程池的高级用法可以显著提升性能:import concurrent.futures import threading from functools import partial from typing import Callable, List, Any class AdvancedThreadPool: def __init__(self, max_workers: int = None, context=None): self.max_workers = max_workers or (threading.cpu_count() * 2) self.context = context self._local_data = threading.local() def _init_worker(self): """初始化工作线程""" if self.context: for key, value in self.context.items(): setattr(self._local_data, key, value) def map_with_context(self, func: Callable, iterable: List[Any], timeout: float = None) -> List[Any]: """带上下文映射""" func_with_init = partial(self._wrap_function, func) with concurrent.futures.ThreadPoolExecutor( max_workers=self.max_workers, initializer=self._init_worker ) as executor: futures = { executor.submit(func_with_init, item): item for item in iterable } results = [] for future in concurrent.futures.as_completed(futures, timeout=timeout): try: results.append(future.result()) except Exception as e: results.append(f"错误: {e}") return results def _wrap_function(self, func, item): """包装函数以访问线程本地数据""" if hasattr(self._local_data, 'user_id'): print(f"在用户上下文 {self._local_data.user_id} 中处理 {item}") return func(item) # 使用高级线程池 def process_item(item): return item * 2 pool = AdvancedThreadPool(context={'user_id': 'user123'}) results = pool.map_with_context(process_item, [1, 2, 3, 4, 5]) print(results) -
内存视图与零拷贝优化
对于高性能计算,理解内存视图和缓冲区协议至关重要:import array import numpy as np from typing import TypeVar, Generic T = TypeVar('T') class ZeroCopyProcessor(Generic[T]): def __init__(self, data: T): self.data = data self._view = None def create_memory_view(self): """创建内存视图以实现零拷贝""" if hasattr(self.data, '__array_interface__'): # NumPy数组 self._view = memoryview(self.data) elif isinstance(self.data, (bytes, bytearray)): # 字节数据 self._view = memoryview(self.data) elif isinstance(self.data, array.array): # 数组 self._view = memoryview(self.data) else: raise TypeError("不支持的数据类型") return self._view def process_slices(self, chunk_size: int = 1024) -> T: """处理数据切片而不复制""" if self._view is None: self.create_memory_view() results = [] for i in range(0, len(self._view), chunk_size): chunk = self._view[i:i + chunk_size] # 零拷贝处理块 processed = self._process_chunk(chunk) results.append(processed) return self._combine_results(results) def _process_chunk(self, chunk): """处理单个块(示例:计算总和)""" return sum(chunk) def _combine_results(self, results): """合并结果""" return sum(results) # 使用零拷贝处理 data = array.array('i', [1, 2, 3, 4, 5] * 1000) processor = ZeroCopyProcessor(data) result = processor.process_slices(chunk_size=100) print(f"处理结果: {result}")
- 高级设计模式与架构
- 依赖注入容器
依赖注入是构建可测试、可维护应用的核心模式:from typing import Dict, Type, Any, Callable from abc import ABC class DIContainer: def __init__(self): self._singletons = {} self._transients = {} self._factories = {} def register_singleton(self, interface: Type, implementation: Type = None): """注册单例""" if implementation is None: implementation = interface self._singletons[interface] = implementation def register_transient(self, interface: Type, implementation: Type = None): """注册瞬时实例""" if implementation is None: implementation = interface self._transients[interface] = implementation def register_factory(self, interface: Type, factory: Callable): """注册工厂函数""" self._factories[interface] = factory def resolve(self, interface: Type) -> Any: """解析依赖""" # 检查工厂 if interface in self._factories: return self._factories[interface]() # 检查单例 if interface in self._singletons: impl = self._singletons[interface] if impl not in self._singletons or self._singletons[impl] is not impl: instance = impl() self._singletons[impl] = instance return instance return self._singletons[impl] # 检查瞬时实例 if interface in self._transients: return self._transients[interface]() raise ValueError(f"未注册的依赖: {interface}") # 使用依赖注入容器 class DatabaseService(ABC): pass class MySQLService(DatabaseService): def __init__(self, connection_string): self.connection_string = connection_string class App: def __init__(self, db_service: DatabaseService): self.db_service = db_service container = DIContainer() container.register_singleton(DatabaseService, MySQLService) container.register_factory(str, lambda: "mysql://localhost") try: app = container.resolve(App) except ValueError as e: print(f"依赖解析: {e}") - 事件驱动架构
事件驱动架构支持高度解耦的系统设计:from typing import Callable, Dict, List, Any from dataclasses import dataclass from enum import Enum import asyncio class EventType(Enum): USER_CREATED = "user_created" ORDER_PLACED = "order_placed" PAYMENT_PROCESSED = "payment_processed" @dataclass class Event: type: EventType data: Any source: str class EventBus: def __init__(self): self._handlers: Dict[EventType, List[Callable]] = {} self._queue = asyncio.Queue() self._is_running = True def subscribe(self, event_type: EventType, handler: Callable): """订阅事件""" if event_type not in self._handlers: self._handlers[event_type] = [] self._handlers[event_type].append(handler) def unsubscribe(self, event_type: EventType, handler: Callable): """取消订阅""" if event_type in self._handlers: self._handlers[event_type].remove(handler) async def publish(self, event: Event): """发布事件到队列""" await self._queue.put(event) async def start_processing(self): """开始处理事件""" while self._is_running: try: event = await asyncio.wait_for(self._queue.get(), timeout=1.0) await self._process_event(event) except asyncio.TimeoutError: continue async def _process_event(self, event: Event): """处理单个事件""" if event.type in self._handlers: for handler in self._handlers[event.type]: try: if asyncio.iscoroutinefunction(handler): await handler(event) else: handler(event) except Exception as e: print(f"事件处理错误: {e}") def stop(self): """停止事件处理""" self._is_running = False # 使用事件总线 async def handle_user_created(event: Event): print(f"处理用户创建: {event.data}") async def main(): event_bus = EventBus() event_bus.subscribe(EventType.USER_CREATED, handle_user_created) # 启动事件处理 processor = asyncio.create_task(event_bus.start_processing()) # 发布事件 await event_bus.publish(Event( type=EventType.USER_CREATED, data={"user_id": 123, "name": "Alice"}, source="auth_service" )) await asyncio.sleep(0.1) event_bus.stop() await processor # asyncio.run(main())
- 元编程与编译器优化
- AST操作与代码生成
抽象语法树操作允许在编译时修改代码行为:import ast import inspect from textwrap import dedent class LoggingTransformer(ast.NodeTransformer): """AST转换器,自动添加日志""" def visit_FunctionDef(self, node): # 为函数添加日志语句 log_stmt = ast.Expr( value=ast.Call( func=ast.Name(id='print', ctx=ast.Load()), args=[ast.Constant(value=f"调用函数: {node.name}")], keywords=[] ) ) node.body.insert(0, log_stmt) return node def compile_with_logging(func): """编译时添加日志的装饰器""" source = inspect.getsource(func) tree = ast.parse(dedent(source)) transformer = LoggingTransformer() new_tree = transformer.visit(tree) ast.fix_missing_locations(new_tree) code_obj = compile(new_tree, '<string>', 'exec') # 在新作用域中执行编译的代码 namespace = {} exec(code_obj, namespace) return namespace[func.__name__] # 应用AST转换 @compile_with_logging def example_function(x, y): result = x + y print(f"结果: {result}") return result # 转换后的函数会自动添加日志 example_function(10, 20)
- 性能分析与优化高级技术
- 字节码优化与缓存策略
理解Python字节码可以帮助进行底层优化:import dis import time from functools import lru_cache from dataclasses import dataclass @dataclass class OptimizationProfile: call_count: int = 0 total_time: float = 0 cache_hits: int = 0 def profile_optimizations(func): """优化分析装饰器""" profile = OptimizationProfile() def wrapper(*args, **kwargs): profile.call_count += 1 start = time.perf_counter() try: result = func(*args, **kwargs) return result finally: end = time.perf_counter() profile.total_time += (end - start) wrapper.profile = profile return wrapper class SmartCache: def __init__(self, maxsize=128, ttl=300): self.maxsize = maxsize self.ttl = ttl self._cache = {} self._hits = 0 self._misses = 0 def cached(self, func): """智能缓存装饰器""" def wrapper(*args, **kwargs): key = self._make_key(args, kwargs) if key in self._cache: timestamp, value = self._cache[key] if time.time() - timestamp < self.ttl: self._hits += 1 return value # 缓存未命中 result = func(*args, **kwargs) self._cache[key] = (time.time(), result) self._misses += 1 # 清理过期缓存 self._cleanup() return result wrapper.cache_info = lambda: { 'hits': self._hits, 'misses': self._misses, 'size': len(self._cache) } return wrapper def _make_key(self, args, kwargs): """创建缓存键""" return (args, tuple(sorted(kwargs.items()))) def _cleanup(self): """清理过期缓存""" current_time = time.time() expired_keys = [ key for key, (timestamp, _) in self._cache.items() if current_time - timestamp > self.ttl ] for key in expired_keys: del self._cache[key] # 使用智能缓存 smart_cache = SmartCache(maxsize=100, ttl=60) @smart_cache.cached @profile_optimizations def expensive_operation(n): """模拟昂贵操作""" time.sleep(0.1) return n * n # 测试缓存效果 for i in [5, 5, 10, 5, 10]: # 重复值测试缓存 result = expensive_operation(i) print(f"expensive_operation({i}) = {result}") print("缓存统计:", expensive_operation.cache_info()) print("性能分析:", expensive_operation.profile)
第21课.Python3编程实战开发(CAM脚本开发)
第22课.Python3编程实战开发(Line_Hooks开发)
第23课.Python3编程实战开发(脚本全自动执行)
第24课.Python3编程实战开发(外挂脚本执行)
第六章.项目开发学习
第25课.快板系统项目详解
-
2.制作规范的标准化建设
操作流程制定
- 工程作业基本流程制定

执行标准建立
操作指引建立
3.实施过程的标准管控
制作项目建立
任务计划排定
任务计划追踪
三、自动化
四、切片化
五、智能化
六、无人化
总结
提示:持续更新中......

1179





