编程方式:java
面向过程: 根据代码在脚本的堆叠顺序,从上到下依次执行python
函数式编程:将相同功能的代码封装到函数中,直接调用便可,减小代码重复性c++
面向对象:对函数进行分类和封装,将同类的函数放到一个类中,使调用更简单sql
为嘛要面向对象编程
应用需求
要的对系统的cpu、内存、硬盘等进行监控,超过阈值则告警服务器
while True: if cpu利用率 > 90%: #发送邮件提醒 链接邮箱服务器 发送邮件 关闭链接 if 硬盘使用空间 > 90%: #发送邮件提醒 链接邮箱服务器 发送邮件 关闭链接 if 内存占用 > 80%: #发送邮件提醒 链接邮箱服务器 发送邮件 关闭链接
随着python的学习,开始使用函数式编程多线程
def 发送邮件(内容) #发送邮件提醒 链接邮箱服务器 发送邮件 关闭链接while True: if cpu利用率 > 90%: 发送邮件('CPU报警') if 硬盘使用空间 > 90%: 发送邮件('硬盘报警') if 内存占用 > 80%: 发送邮件('内存报警')
函数式编程增长了代码的可读性和重用性,可是,这仅仅是单台机器的监控,若是我要监控多台呢,可能须要须要这样写:编程语言
def 发送邮件(内容) #发送邮件提醒 链接邮箱服务器 发送邮件 关闭链接while True:for host in host-list: #经过遍历host列表来进行监控 if cpu利用率 > 90%: 发送邮件('CPU报警') if 硬盘使用空间 > 90%: 发送邮件('硬盘报警') if 内存占用 > 80%: 发送邮件('内存报警')
这样貌似实现了,可是若是是1000台机器呢,可能当循环到999台的时候,第100台已经出现问题了。形成告警延误。而若是使用面向对象呢?将很好的解决此问题ide
class host:def 发送邮件(内容) #发送邮件提醒 链接邮箱服务器 发送邮件 关闭链接def judge(self):while True: if cpu利用率 > 90%: 发送邮件('CPU报警') if 硬盘使用空间 > 90%: 发送邮件('硬盘报警') if 内存占用 > 80%: 发送邮件('内存报警')
我将每一个机器建立为一个对象,对象中有上面判断的方法,这样我就能够多线程的监控函数式编程
类和对象
类就是一个模板,模板里能够包含多个方法(即函数),方法里实现一些功能,对象则是根据模板建立的实例,经过实例对象能够执行类中的函数
建立类和对象
#建立类 class+类名class foo: #class是关键字,表示类,foo是类的名字def f1(self): #类的方法1passdef f2(self): #类的方法2pass#建立对象 对象 = 类名()bar = foo() #建立一个bar对象 ,此对象中有类中全部的方法 ,建立对象,类名称后加括号便可#调用对象的方法 对象.方法名()bar.f1()bar.f2()
举例:
#建立类class SQL: def create(self,sql): print(sql) def modify(self, sql): print(sql) def remove(self,sql): print(sql) def fetch(self,sql): print(sql)#建立对象obj1 = SQL()obj2 =SQL()#调用对象里的方法res1 = obj1.modify('修改')res2 = obj2.fetch('查看')print('obj1:'res1)print('obj2:'res2)运行结果:obj1: 修改obj2: 查看
应用场景
面向对象:【建立对象】【经过对象执行方法】,适用于当某一些函数中具备相同参数时,可使用面向对象的方式,将参数值一次性封装到对象里,函数直接调用便可
函数编程:【执行函数】 各个函数之间是独立且无共用的数据
类中的self是什么鬼
self是python自动传值的一个形式参数,那个对象调用方法,就会自动执行self,在一个类中,self就是对象自己
还用上面的例子,若是我须要在执行方法的时候,验证用户名、密码传,验证经过以后才能执行里面的方法,那我须要建立对象以后,进行赋值用户密码
class SQL:def modify(self, sql): print(sql) print(self.name) print(self.passwd) def remove(self,sql): print(sql) print(self.name) print(self.passwd) def fetch(self,sql): print(sql) print(self.name) print(self.passwd)#建立对象obj1 = SQL()obj1.user = 'user'obj1.passwd = 'passwd'res1 = obj1.modify('修改')res2 = obj2.fetch('结果')print(res1)print(res2)输出结果:修改userpasswd结果userpasswd
咱们使用self来定义user和passwd变量,这样user和passwd对整个对象是生效的,因此在每一个方法都均可以调用到
类的构造方法
上例发现每次对象调用方法都要进行对user 和password进行赋值。很是麻烦。
python类中使用init自动构造方法,当建立对象的时候自动执行该方法。以下使用init,这样我只须要定义一次便可
class SQL:def __init__(self,user,password): self.user = user self.password = password def create(self,sql): print(sql) print(self.name) print(self.passwd) def modify(self, sql): print(sql) print(self.name) print(self.passwd) def remove(self,sql): print(sql) print(self.name) print(self.passwd) def fetch(self,sql): print(sql) print(self.name) print(self.passwd)obj1 = SQL('username','password')obj1.remove()obj2 = SQL('username1','password1')obj2.remove()
封装
封装,顾名思义就是将内容封装到某个地方,之后再去调用被封装在某处的内容。因此,在使用面向对象的封装特性时,须要:
将内容封装到某处
class SQL: def __init__(self,name,passwd): #类的构造方法,自动执行 self.name = name self.passwd = passwd def create(self,sql): #类的一个方法 print(sql,self.name,self.passwd)#建立类SQL的obj对象obj1 = SQL('fuzj','123') #自动fuzj和123分别封装到对象obj1的name和asswd属性中obj2 = SQL('jie','311') #自动jie和311分别封装到对象obj2的name和asswd属性中
从某处调用被封装的内容
方式1 经过对象直接调用
res = obj1.name #直接调用obj的user属性res2 = obj1.passwd #直接调用obj的passwd属性print(res,res2)输出结果:fuzj 12313
方式2 经过self间接调用
res3 = obj1.create('fasdasda')print(res3)输出结果:fasdasda fuzj 12313
多重封装
类不只能够将普通字符串封装到类中,还能够将一个对象封装到类中,看下面代码
#建立类class SQL: def __init__(self,name,passwd): self.name = name self.passwd = passwd def create(self,sql): print(sql)class test: def __init__(self,name,obj): self.name = name self.obj = obj def add(self,arg): print(arg)class test2: def __init__(self,obj): self.obj = obj def iner(slef,arg): print(arg)#建立对象c1 = SQL('fuzj','12313')c2 = test('aaa',c1) #把c1对象封装到c2对象里,c2对象会有c1对象的全部方法c3 = test2(c2) #把c2对象封装到c3对象中,c3对象会有c2对象的全部方法,同时也就有了c1对象的全部方法#调用c1.create("c1调用自身create方法")c2.obj.create('c2调用c1的create方法')c3.obj.add('c3调用c2的add方法')c3.obj.obj.create('c3调用c1的create方法')结果:c1调用自身create方法c2调用c1的create方法c3调用c2的add方法c3调用c1的create方法
能够看出,将a对象封装到b对象中,b对象也就有了a对象的全部方法,
其关系如图:
因此c3若是要使用c1的create的方法,须要以下调用
c3.obj.obj.create()
继承
类的继承是子类继承父类的全部方法,或者说基类继承派生类的全部方法
class 父类: def 方法1(slef): passclass 子类(父类): pass那么子类中就会有父类的方法1
* 单继承 一个子类只继承一个父类 以下:
class c1: def __init__(self): self.name = 'c1' self.user = 'c1uer' def test(self): print("c1_test") def test1(self): print("c1_test1") def test3(self): self.test()class c2(c1): def __init__(self): self.passwd = 'c2' def test(self): print("c2_test") def test2(self): self.test3()obj = c2()obj.test()obj.test1()obj.test2()执行结果:c2_testc1_test1c2_test
继承规则:
1) 调用子类的某个方法时,若是这个方法在子类中存在,则执行子类的方法,若是子类方法不存在,再去找父类的方法。因此执行obj.test()时,子类中有该方法,就直接执行该方法,再也不父类中找,所以返回结果是c2_test;执行obj.test1()时,子类中没有改方法,就找到父类的方法,再执行,所以返回的结果是c1_test1
2) 子类的方法优先于父类的方法,当父类的方法中有调取其余方法时,会优先查找子类的方法,因此执行c2_test2()时,发现该方法调用的时是test3(),因而开始从本身方法中查找test3(),而后再去找父类中的方法,找到父类的test3()方法,发现该方法调用了test()方法,因而会再次查找test()方法,发现本身有,因此就直接调用本身的test()方法,返回c2_test
3) 子类继承父类,其实就是将父类中的方法子类中没有的所有挪到子类下
* 多继承 * python的子类能够继承多个父类,这是比java、c++等开发语言最大的优点 单父继承,即没有共同的父类,规则为一条道走到黑
class 父类1:passclass 父类2:passclass 子类(父类1,父类2)pass那么,子类中就会有父类1,父类2的全部方法
#c4继承了c2,c3两个父类,c2继承了c1父类,c3和c1中都有test()的方法class c1: def test1(self): print("c1_test") def test(self): print("c1_test")class c2(c1): def test2(self): print('c2_test')class c3: def test3(self): print("c3_test") def test(self): print("c3_test")class c4(c2,c3): def test4(self): print('c4_test')obj = c4()obj.test()obj.test3()运行结果:c1_testc3_test从结果能够看出:obj.test()执行顺序为:首先去c4类中查找,若是c4类中没有,则继续去c2类中找,若是c2类中没有,则继续去父类c1类中找,因此test()打印的结果为c1_testobj.test3()执行顺序为:首先去c4类中查找,若是c4类中没有,则继续去c2类中找,若是c2类中没有,则继续去父类c1类中找,c1没有,则返回继续去另外一个c4的父类c3中找,因此test3()打印的结果为c3_test
继承规则:
1)子类中有两个父类,会从左到右依次查找父类的方法
2)子类的父类若是还有继承,优先查找当前父类的父类
3)多继承的每次查找父类仍然遵循单继承的原则
即
同父继承,最上边有继承的是一个父类,状况则不同了
#c4继承c2和c3两个父类,c2继承c1父类,c3继承c0父类,c0和c1继承c父类class c: def test(self): print("c_test")class c0(c): def test(self): print("c0_test")class c1(c): def test1(self): print("c1_test")class c2(c1): def test2(self): print('c2_test')class c3(c0): def test3(self): print("c3_test")class c4(c2,c3): def test4(self): print('c4_test')obj = c4()obj.test()运行结果:c0_test查找顺序为:1.查找c4中是否有test()方法,若是没有则查找c2中,c2中没有则查找c1中,c1中没有,不会继续查找父类了,会反回来查找c3类,c3类没有则找c0类,最后返回结果
该规则一样适用下面状况
多态
Pyhon不支持多态而且也用不到多态,多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”
多态中python和其余编程语言最大的区别是传参问题。python的函数传参,参数能够是列表,字典,字符串,数字等,而java、c++等语言传递参数时,参数须要指定类型,一旦参数类型被指定,就只能处理此中类型的数据
举例:
python:
def func(arg):passarg 能够是字符串、数字、列表、字典等
java或c++
def func(int,arg)passarg 只能处理int类型的数据def func(str,arg)passarg只能处理字符串类型的数据,若是数据类型不符合的话。直接报错
java如何支持多态
class A:passclass B(A):passclass C(A)passdef func(B,arg):pass此时arg指定类型为B,那么只能为B的对象类型def func(A,arg)pass此时指定arg类型为A类型,而B和C都继承A,因此ABC类型均可以使用了因此相似java的编程语言,都是利用类的继承关系来实现多态