第三章
对象:特征与技能的结合体
类:类是一系列对象相似的特征与相似的技能的结合体
类
第一个大用途:对属性的操作
查看类的属性:
LuffyStudent.school == LuffyStudent.__dict__['school']
增:
LuffyStudent.county = "China"
删:
del LuffyStudent.county
改:
LuffyStudent.county ="USA"
__dict__ 输出命名空间的字典
__init__ 方法用来为对象定制对象自己的独有特征
加上__init__方法后,实例化的步骤
1.先产生一个空对象obj
2.初始化obj
3.返回值obj
类中的函数属性:绑定到对象使用的,绑定到不同的对象是不同的绑定方法,对象调用绑定方式时,会把对象本身当做第一个参数self
类调用类里的函数 为一个普通函数的调用
查找顺序:对象--》类--》父类
继承的实现原理
1.
子类中重用父类的属性
1.指明道姓的方法 #不依赖继承
2.super() #依赖继承
super() 它其实是会在self 里面的mro列表里面继续查找
class A:
def test(self):
super().test()
class B:
def test(self):
print('from B')
class C(A,B):
pass
c=C()
c.test() #打印结果:from B
组合:
类里面调用另一个类的方法
抽象类 #只能被继承,不能被实例化
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod #加了装饰器,子类继承时,必须要有run方法
def run(self):
pass
多态 #同一种事物的多种形态
多态性 #指的是可以在不考虑对象的类型的情况下直接使用对象
静态多态性:
‘+’ 可以是字符串,列表,数字 之间的相加,站在‘+’角度考虑,‘+’无须考虑两边的类型,这就叫静态多态性
鸭子类型
看得像鸭子 就可以了 python崇尚鸭子类型
封装
__x = 1 # _类名__x = 1
特点:
1.在类外部无法直接 obj.__AttrName
2.在类内部可以直接使用:obj.__AttrName (因为在类定义的时候,已经将隐藏类改成了可以正确访问的格式--》 _obj__AttrName)
3.子类无法覆盖父类__开头的属性
变形的过程只发生在类定义阶段,之后再定义__x 并不会发生变形
封装意义:
1.封装数据属性:明确的区分内外,控制外部对隐藏的属性的操作行为
2.隔离复杂度
在类内部定义的函数,分为两大类:
一:绑定方法:绑定给谁,就应该由谁来调用,谁来调用就回把调用者当作第一个参数自动传入
绑定到对象的方法:在类内定义的没有被任何装饰器修饰的
就是我们在一个类里面,普通定义一个函数
绑定到类的方法:在类内定义的被装饰器classmethod修饰的方法
在一个类里,定义一个函数时前 加一个装饰器
二:非绑定方法:没有自动传值这么一说了,就类中定义的一个普通工具,对象和类都可以使用
非绑定方法:不与类或者对象绑定
同理 加一个装饰器 @staticmethod
反射:通过字符串映射到对象的属性
hasattr : 查看是否存在
getattr : 获取
setattr : 更改
delattr : 删除
内置方法:
__str__ 会在打印print 时触发该方法
f.open() #操作系统打开了,但需要回收资源
f.close() #所以需要close,但这时候f的程序资源还是存在,会在程序关闭后python自动关闭
__del__ 会在对象被删除后运行del操作
exec
储备知识exec
参数1:字符串形式的命令
参数2:全局作用域(字典形式),如果不指定默认就使用globals()
参数3:局部作用域(字典形式),如果不指定默认就使用locals()
#一切皆对象,对象可以怎么用?
#1、都可以被引用,x=obj
#2、都可以当作函数的参数传入
#3、都可以当作函数的返回值
#4、都可以当作容器类的元素,l=[func,time,obj,1]
类实际是type(.....) 实例
产生类的类称之为元类,默认所以用class定义的类,他们的元类是type
定义类的三要素:类名,类的基类们,类的名称空间
class_name='Chinese'
class_bases=(object,)
class_body="""
country='China'
def __init__(self,namem,age):
self.name=namem
self.age=age
def talk(self):
print('%s is talking' %self.name)
"""
class_dic={}
exec(class_body,globals(),class_dic)
chinese = type(class_body,class_bases,class_dic)
自定义元类 控制
1.只有在python2中才分新式类和经典类,python3中统一都是新式类
2.在python2中,没有显式的继承object类的类,以及该类的子类,都是经典类
3.在python2中,显式地声明继承object的类,以及该类的子类,都是新式类
4.在python3中,无论是否继承object,都默认继承object,即python3中所有类均为新式类
静态方法
静态方法主要是用来存放逻辑性的代码,主要是一些逻辑属于类,但是和类本身没有交互,即在静态方法中,不会涉及到类中的方法和属性的操作。可以理解为将静态方法存在此类的名称空间中。
静态方法就是加 装饰器@staticmethod
property
将类中的方法 装饰成一个数据属性,要有返回值 即name ,age 这种就为数据属性
__call__ 在实例化 传参数时调用
所有类的元类 默认是type
class Chinese(object,metaclass=Mymeta)
在元类重写时 需要重写__init__ 同时需要用到type其他的方法,可以:
super(类名,self).__init__(class_name,class_base,class_dict)
__call__ 在对象调用时会触发
class Foo:
def __call__(self, *args, **kwargs):
print('hi)
obj = Foo() #没调用
obj() #调用了
__call__ 方法里面,我们传参进去,然后再得返回值obj,其实call里面会做三件事
1.先新造一个对象obj
2.初始化obj
3.返回obj
所以当我们重写call方法时,就是要做这三件事情
1.所有类都会继承object ,object里面有一个方法new就是新建
即 obj = object.__new__(self) #self就是你的类名
2.初始化 初始化就是用__init__ 方法,这就用到类下面的init,就是用 self.__init__(obj,*args, **kwargs)
init用得类的创建
call用得是类创建之后的实例化
网络编程
应用软件--》操作系统--》硬件系统
物理层
数据链路层 Ethernet
数据包 head(18字节,6:自己地址MAC,6:目标地址MAC,6:数据描述) + data 无限制
TCP/UDP
TCP:三次握手,建立连接(管道)。断开连接需要三次,因为不知道服务端到客户端传完数据没有,所以不能合并一次。效率低,但可靠
UDP:只管向外发送数据,效率高,不可靠
套接字,就是在应用层和传输层之间的一个socket抽象层里的关键字
0-65535:0-1024给操作系统使用
C客户端 send 实际是发送给操作系统,操作系统再调用网卡发送
S服务端 recv 实际也是收操作系统的
粘包现象:
就是在管道里面数据堆积在一起
终极版解决粘包问题
先制造一个字典dic,里面包含着多种信息,如文件名,data的大小等等
第一步:把dic,json序列化后打包发送他的len,先发送报头的长度部分
第二步:发送报头dic
第三步:发送真实的数据