最近把python基础又过了一遍 今天特意下班留公司想把最近学到的知识总结一下
python这些优点大家都知道 但是什么是解释型 什么是面向对象 什么又是动态型语义
- 解释型
在计算机中都是以二进制存储的非0即1这片文章解释的很明白 计算机二进制存储 解释性语言C 和 C++ 在运行时可以直接转为计算机能读懂的二进制的语言。而python语言不需要编译成二进制代码,python解释器会把你的代码转换为字节码再把它编译成二进制语言并运行。
- 面向对象中的对象其三个特征
python使用对象模型来存储数据。构造任何类型的值都是一个对象。
id 即为系统内存分配的每个对象的地址
type 类型 标明每个对象的类型比如整形或是字符串
value 存储的值 用户输入用户所表示的数据
- 面向对象的主要技术还有一下特征
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
局部变量:定义在方法中的变量,只作用于当前实例的类。
实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
- 动态语义
动态语义即为在用变量时不用声明类型 可以更好的提高开发效率
字典核心的底层原理
大家都知道在列表中要取出一个对象用索引即可,用了字典后发现要获得一个值是用键去找。
其实字典实现的核心也是用数组实现的 在这里叫散列表 散列表本身就是一个数组 我们称为稀疏数组(此数组不会溢出,总有空白元素) 每一个数组的单元都叫 bucket (附上图片)
一个bucket分为键和值俩部分 由于bucket结构和大小一致,我们可以通过偏移量来读取指定bucket
在查找一个key时可以找到对应的value以及它的索引(对应上图)
在构造一个字典时 python 首先会调用hash()方法求的字典键的散列值并转为2进制(如下图)
得到二进制哈希后从后往前数假如以后三位开始取散列值右侧3位二进制数和散列数组的索引比较 查看偏移量为二进制代表的数是否为空 如果为空就把键的内存id填写。
如果不为空则继续再继续往右取散列值三位数直到找到对应索引为空的bucket
流程图如下
扩容
假设当前数组存储的已经达到总长的3/2 则生成一个更大的数组并且把之前的数据拷到新的数组中
当我们输入键查找对应的值时系统会还是会调用hash()方法求的字典键的散列值并转为2进制
依然假设数组长度为8算列为3
从右向左取三位到数组里找对应的索引位置如果有则计算键对应的哈希散列码如果算完之后与上面查找的散列码后三位对应则直接返回
如果不一样则继续从当前查找的位置再向后取三位继续查找对应的位置
直到找到符合要求并且返回
插入Flowchart流程图
总结
- 字典在内存中的开销巨大,典型的空间换时间
- 键查询速度很快
- 在字典里添加新的内容可能会导致扩容,导致散列表中的键的次序变化因此不要在遍历字典的同时进行字典的修改。如果需要的话可以先遍历再进行修改。