一:计算机基础
巨人思维:
你能想到的问题,基本99%已经有了解决方案,你无需从0开始,先学习别人成熟的解决方案,然后加入自己的。
一:编程语言
编程语言:与计算机交流的语言,有java,c#,Python等,各自有各自的规则和语法,java有自己的编译器,Python有自己的解释器,让高级语言变成计算机可以理解的010101二进制!
os来负责调度硬件,有神级人物帮你写好了接口,语言的翻译过程也有大神级程序员帮我写好了解释器,而我一个菜鸟站在这么多的巨人身上一定可以学好,要不怎么对得起这些大神的付出呢?
我们写的高级语言经过翻译后和os打交道!无法直接控制硬件,相邻层之间紧密联系,绝不跨级联系.
二:计算机硬件介绍
硬件的作用:运行os给的指令
三大件: CPU 内存 硬盘
写好的代码放在硬盘中,运行代码加载到内存,cpu从内存中获取代码执行,解释器翻译为01010代码给os,os将代码通过主板上的"神经"传送到各个硬件来进行工作.
代码无法直接的控制硬件,都是os来进行的,语言的底层是面向的OS提供的接口进行的翻译,程序员则是面向的变成语言进行的编写,之间都有中间人,复杂的难懂的对我们是屏蔽的,我们面向的是更加人性化的高级语言.
三:操作系统的启动流程
1.计算机加电
2.BIOS开始运行,检测硬件:cpu、内存、硬盘等
3.BIOS读取CMOS存储器中的参数,选择启动设备
4.从启动设备上读取第一个扇区的内容(MBR主引导记录512字节,前446为引导信息,后64为分区信息,最后两个为标志位)
5.根据分区信息读入bootloader启动装载模块,启动操作系统
6.然后操作系统询问BIOS,以获得配置信息。对于每种设备,系统会检查其设备驱动程序是否存在,如果没有,系统则会要求用户按照设备驱动程序。一旦有了全部的设备驱动程序,操作系统就将它们调入内核。然后初始有关的表格(如进程表),穿件需要的进程,并在每个终端上启动登录程序或GUI
四:应用程序的启动流程
1.双击快捷方式
2.操作系统从硬盘读取程序文件到内存中
3.cpu从内存中读取数据执行
五:Python程序的启动流程
5.1namespace
import this,最后一句话Namespaces are one honking great idea -- let's do more of those!
名称空间:我们可以看懂的高级语言,计算机看不懂,计算机只认识01010,namespace存放着映射关系,
例如a=100,在内存中变量名a会开内存地址存放,数据100也会开内存地址存放数据100,分别对应两个内存地址。
我们只关心怎么拿到数据,并不关心变量名的内存地址。python解释器也知道,就像一个服务员,说a,那么解释器立马把100给你。
二者的映射关系存放在namespace中,你用程序调用a,Python解释器就知道你要100,这是一种“默契”。
再延伸,你只需要记住要使用的变量名,函数名,模块名,包名,那么解释器就会去帮你找对应的数据和代码块。
背后都是靠namespace来存放的映射关系,namespace的本质就是字典。
5.2python Hello.py的背后经历了什么
第一阶段:python解释器启动,加载内置模块,让如内置ns中。
第二阶段:从硬盘中找到主文件,然后进行词法分析,分析过程中会根据主文件中import的三方模块到内存,硬盘的顺序找对应模块,例如关键字有误时就会报错,如果没有错误继续进行语法分析,例如if...else语法少了if也会报错,如果都没有错误就会生成pyc文件,字节码文件(会记录最后的修改时间,如果变动了就会重新进行编译)。字节码文件在内存中的存在形式是PyCodeObject对象,硬盘中的存在形式是pyc文件。
语法分析阶段就会把类,方法,变量等工具和数据放到合适的位置,就是所谓的namespace,方便python代码运行的时候获取。
例如语法分析时分析到class关键字,就会创建class类对象,分析到def关键字,就会创建funciton对象,不同的变量,例如int就创建int对象,str就创建str对象,他们都是value,而key就是变量名类名,方法名,放入全局ns中。
也是KV理论。
第二阶段可以视为创建对象的阶段,也叫准备工具阶段。
第三阶段:执行阶段,所有需要的工具都准备好了,开始工作直接结束。
首先python执行的入口并不是main,不像java,c++他们程序的入口是main函数,python很灵活,可以用自己的习惯来控制入口,且往往我们把程序的执行逻辑放入if __name__=="__main__":下,做到逻辑与执行分离。只有第三阶段调用函数才会出现局部ns,前两个阶段不会出现局部ns。
上面多次提到的ns在内存中的存在形式就是dict,用key找value,只不过中间用名词ns做了地址的映射,这样才能用key找到value。
总结:不要在引入模块中进行代码逻辑语句的调用,尽管在语法级别python没有对我们进行约束,如果你那样做了会在代码量级上去之后造成逻辑混乱,而是将他们封入类或方法中,统一的放到if __name__="__main__"中进行逻辑的调用。
python很多地方没有进行强制约束,但是大家为了可以高效工作,都是按照约定来约束自己的编码。
内置ns:python解释器启动阶段加载的内置模块都放在这里面
全局ns:不是内置的,也不是函数的,就是全局的。
局部ns:只有函数调用才会产生,函数执行结束就会消失。
ns的加载顺序依次是:内置ns 全局ns 局部ns
查找则依赖倒置正好相反,从当前ns找,没有则向上找找到了就停止,直到内置还没有找到就会报错,所以不要在下层ns中定义和上层ns相同的变量名,假如想要用最上层ns中的数据,但是你在下层ns中定义了相同的名字,解释器找到就不会向上找了.
六:作用域Scope
python中一切皆对象,但是想要反复使用就一定有一个人类可以识别的标记指向,这个标记的名字叫做变量名。
作用域:指变量的生效范围,他是一种规则已经天生存在了。
当全局ns中a=100和内置ns中都有变量名a=1000,那么函数中打印的a是找哪一个呢?
答案是:找全局的ns中的a=100,因为找到了就不再向内置ns中找。
但是我就想让他调用的是内置ns中的a=1000,那么此时计算机只会按照规则办事,无法摸到内置的ns中的a,此时你必须手动的指定a的来源,打印时也明确指出要打印a的,也就是说用ns来明确指明a,即用模块名.a,模块名就是一个ns的名称
namespace的作用范围就是作用域
内置ns 全局ns在任何位置都可以访问到,归为全局作用域,有关键字global来
局部ns只能在局部发挥作用,函数内部起作用,外部无法访问局部ns中定义的变量
七:总结
python中一切皆对象,就算模块.py文件也是以对象的形式存在,之所以可以这样全部归功于元类在背后默默的创建着各个对象。
python之所以流行一是简单易学,二是因为三方模块达13万之多,可以在各个领域发挥作用。假如go也有这么多的模块,势必超过python。
总览python:就是一堆字典,key存放变量名,value对象对象的地址,要么就是key存放一个小的字段的名字,value存放字典的地址。
这堆字典里面有三个“老大字典”牵头,内置,全局,局部,然后各个小字典嵌套在他们里面。
只要使用对应的ns的名字,a.b.c来获取想要的数据来服务程序。
在if __name__=="__main__"中使用,偶尔插入一些异常处理而已。
真正的高手是设计软件,而非只是写出功能而已,更多的是软件的可扩展性,可维护性。