• python 自动化之路 day 面向对象基础


    1.面向對象基础概述

    • 面向过程:
    • 根据业务逻辑从上到下垒代码(如果程序修改,对于依赖的过程都需要进行修改。)
    • 函数式:
    • 将某功能代码封装到函数中,如后便无需重复编写,仅需要调用函数即可
    • 面向对象:
    • 世界万物,皆可分类。
    • 世界万物,皆为对象。
    • 只要是对象,就肯定属于某种品类。
    • 只要是对象,就肯定有属性(名称或功能)
    • 对函数进行分类和封装,让开发"更快、更好、更强"

    无论用什么形式来编程,我们都要明确记住以下原则: 
    1.写重复代码是非常低级的行为 
    2.你写的代码需要经常变更

    1.面向对象编程方式实现监控报警(最容易被初学者接受):

     
    1. whileTrue
    2.   if cpu利用率>90%:
    3.     #发送邮件提醒
    4.   连接邮箱服务器
    5.   发送邮件
    6.   关闭连接
    7.   if硬盘使用空间>90%:
    8.     #发送邮件提醒
    9.   连接邮箱服务器
    10.   发送邮件
    11.   关闭连接
    12.   if内存占用>80%:
    13.   #发送邮件提醒
    14.   连接邮箱服务器
    15.   发送邮件
    16.   关闭连接

    2.随着时间的推移,开始使用了函数式编程,增强代码的重用性和可读性

     
    1. def发送邮件(内容)
    2.   #发送邮件提醒
    3.   连接邮箱服务器
    4.   发送邮件
    5.   关闭连接
    6. whileTrue
    7.   if cpu利用率>90%:
    8.   发送邮件('CPU报警')
    9.   if硬盘使用空间>90%:
    10.   发送邮件('硬盘报警')
    11.  if内存占用>80%:
    12.   发送邮件('内存报警')

    3.今天我们来使用面向对象编程(OOP面向对象程序设计)

     

    1.1创建类和对象

    面向对象编程是一种编程方式,此变成方式和落地需要使用"类(class)"和"对象(object)"来实现,所以,面向对象编程其实就是对"类"和"对象"的使用。

    • 类就是一个模板,模板里可以包含多个函数,函数里实现具体功能(把一个类变成具体的过程叫做实例化。)
    • 对象则是根据模板创建的实例,通过实例对象可以执行类中的函数
     
    1. #class:关键字,表示要创建类
    2. #F1:类的名称
    3. #self:形式参数(必填)
    4. # 创建类
    5. class F1:
    6.     # 创建类中的函数
    7.     def bar(self):
    8.         print("bar")#可以是功能模块
    9. # 根据类F1创建对象obj
    10. obj = F1()#创建对象,类名称后加括号即可

    这么说可能有一些抽象,我们来看一个具体的例子:

     
    1. # 创建类
    2. class F1:
    3.     def bar(self):
    4.         print("bar")
    5.     def Hello(self, name):
    6.         self.name = name
    7.         print("i am %s"%self.name)
    8. # 根据类F1创建对象obj
    9. obj = F1()
    10. obj.bar()#执行bar方法
    11. obj.Hello("xuliangwei")#执行hello方法

    你在这里是不是有疑问了?使用函数式编程和面向对象编程方式来执行一个“方法”时函数要比面向对象简便

    面向对象:【创建对象】【通过对象执行方法】 
    函数编程:【执行函数】 
    观察上述对比答案则是肯定的,然后并非绝对,场景的不同适合其的编程方式也不同。 
    总结:函数式的应用场景 -->各个函数之间是独立且无共用的数据

     

    1.2面向对象三大特征

    面向对象的三大特性:封装、继承、多态。

     

    1.2.1封装

    在类中对数据的赋值,内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法。

    1.封装

     
    1. # 创建类
    2. class F2:
    3. #init构造函数,在实例化时做一些类的初始化的工作
    4. def __init__(self, name, age):
    5. self.name = name
    6. self.age = age
    7. # 根据类F2创建对象
    8. # 自动执行F2类的__init__方法
    9. obj1 = F2('xulaingwei',18)
    10. #将xuliangwei和18分别封装到obj1和self的name、age属性中
    11. # 根据类F2创建对象
    12. # 自动执行F2类的__init__方法
    13. obj2 = F2('jack',58)
    14. #将Jack和58分别封装到obj2和self的name、age属性中

    2.调用封装的内容时,有两种调用情况:

    • 1.通过对想直接调用
     
    1. # 创建类
    2. class F2:
    3. def __init__(self, name, age):
    4. self.name = name
    5. self.age = age
    6. obj1 = F2('xulaingwei',18)
    7. print(obj1.name,obj1.age)#直接调用obj1对象的name age属性
    8. obj2 = F2('jack',58)
    9. print(obj2.name,obj2.age)#直接调用obj2对象的name age属性
    • 2.通过self间接调用 
      执行类中的方法时,需要通过self间接调用被封装的内容
     
    1. # 创建类
    2. class F2():
    3. def __init__(self,name,age):
    4. self.name = name
    5. self.age = age
    6. def detail(self):
    7. print(self.name)
    8. print(self.age)
    9. obj1 = F2('xuliangwei',18)
    10. obj1.detail()# Python默认会将obj1传给self参数,即:obj1.detail(obj1),所以,此时方法内部的 self = obj1,即:self.name 是 xuliangwei ;self.age 是 18
    11. obj2 = F2('jack',58)
    12. obj2.detail()# Python默认会将obj2传给self参数,即:obj2.detail(obj2),所以,此时方法内部的 self = obj2,即:self.name 是 jack ;self.age 是 58

    综上所述,对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self间接获取被封装的内容。

    练习题:在终端输出如下信息

     
    1. 小明,10岁,男,上山去砍柴
    2. 小明,10岁,男,开车去东北
    3. 小明,10岁,男,最爱大保健
    4. 老李,90岁,男,上山去砍柴
    5. 老李,90岁,男,开车去东北
    6. 老李,90岁,男,最爱大保健

    函数式编程方法:

     
    1. def kanchai (name, age, gender):
    2. print("%s,%s岁,%s,上山砍柴"%(name,age,gender))
    3. def qudongbei(name, age, gender):
    4. print("%s,%s岁,%s,开车去东北"%(name, age, gender))
    5. def dabaojian(name, age, gender):
    6. print("%s,%s岁,%s,最爱大保健"%(name, age, gender))
    7. kanchai('小明',10,'男')
    8. qudongbei('小明',10,'男')
    9. dabaojian('小明',10,'男')
    10. kanchai('老李',90,'男')
    11. qudongbei('老李',90,'男')
    12. dabaojian('老李',90,'男')

    面向对象编程方法:

     
    1. #!/usr/bin/env python
    2. # Author:xuliangwei
    3. class F1:
    4. #init构造函数
    5. #在实例化时做一些类的初始化的工作
    6. def __init__(self,name,age,gender):
    7. self.name = name
    8. self.age = age
    9. self.gender = gender
    10. def kanchai(self):
    11. print("%s,%s岁,%s,上山砍柴"%(self.name,self.age,self.gender))
    12. def qudongbei(self):
    13. print("%s,%s岁,%s,开车去东北"%(self.name,self.age,self.gender))
    14. def dabaojian(self):
    15. print("%s,%s岁,%s,最爱大保健"%(self.name,self.age,self.gender))
    16. obj1 = F1('小明',10,'男')
    17. obj1.kanchai()
    18. obj1.qudongbei()
    19. obj1.dabaojian()
    20. obj2 = F1('老李',90,'男')
    21. obj2.kanchai()
    22. obj2.qudongbei()
    23. obj2.dabaojian()
    24. #上述对比可以看出,如果使用函数式编程,需要在每次执行函数时传入相同的参数,如果参数多的话,又需要粘贴复制了... ;而对于面向对象只需要在创建对象时,将所有需要的参数封装到当前对象中,之后再次使用时,通过self间接去当前对象中取值即可。
     

    1.2.2继承

    一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承。 
    例如: 
      猫可以:喵喵叫、吃、喝、拉、撒 
      狗可以:汪汪叫、吃、喝、拉、撒

     
    1. class mao:
    2. def喵喵叫(self):
    3. print("喵喵叫")
    4. def吃(self):
    5. print("吃")
    6. def喝(self):
    7. print("喝")
    8. def拉(self):
    9. print("拉")
    10. def撒(self):
    11. print("撒")
    12. class gou:
    13. def汪汪叫(self):
    14. print("汪汪叫")
    15. def吃(self):
    16. print("吃")
    17. def喝(self):
    18. print("喝")
    19. def拉(self):
    20. print("拉")
    21. def撒(self):
    22. print("撒")

    上述代码不难看出,吃、喝、拉、撒是猫和狗都具有的功能,而我们却分别的猫和狗的类中编写了两次。 
    如果使用”继承“的思想,如下实现: 
       动物:吃、喝、拉、撒 
       猫:喵喵叫(猫继承动物的功能) 
       狗:汪汪叫(狗继承动物的功能)

     
    1. classAnimal:
    2. def eat(self):
    3. print("%s 吃 "%(self.name))
    4. def drink(self):
    5. print("%s 喝 "%(self.name))
    6. def shit(self):
    7. print("%s 拉 "%(self.name))
    8. def pee(self):
    9. print("%s 撒 "%(self.name))
    10. classCat(Animal):
    11. def __init__(self, name):
    12. self.name = name
    13. self.breed ='猫'
    14. def cry(self):
    15. print('%s 喵喵叫-->%s'%(self.name,self.breed))
    16. classDog(Animal):
    17. def __init__(self, name):
    18. self.name = name
    19. self.breed ='狗'
    20. def cry(self):
    21. print('%s 汪汪叫-->%s'%(self.name,self.breed))
    22. # ######### 执行 #########
    23. c1 =Cat('小黑猫')
    24. c1.cry()
    25. c1.eat()
    26. c1.drink()
    27. d1 =Dog('小瘦狗')
    28. d1.cry()
    29. d1.eat()
    30. d1.drink()
    31. d1.pee()
    32. ##对于面向对象性继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法.(避免重复造轮子)
    33. 注:除了子类和父类的称谓,你可能看到过派生类基类,他们与子类和父类只是叫法不同而已。
     

    1.2.3多级继承

    1.Python的类可以继承多个类,Java和C#中则只能继承一个类 
    2.Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先 
    深度优先以及广度优先

    python2经典类,按深度优先来继承的。 
    python2新式类,按广度有限来继承的。 
    python3经典类,新式类 是按广度优先来继承的。

    • 经典类(深度优先) 
      当类是经典类时,多继承情况下,会按照深度优先方式查找
     
    1. #经典类写法
    2. class A1:
    3. pass
    4. class A2(A1):
    5. pass

    经典类,实践测试

     
    1. class D:
    2. def bar(self):
    3. print('D.bar')
    4. class C(D):
    5. def bar(self):
    6. print('C.bar')
    7. class B(D):
    8. def bar(self):
    9. print('B.bar')
    10. class A(B, C):
    11. def bar(self):
    12. print('A.bar')
    13. a = A()
    14. a.bar()
    15. # 执行bar方法时
    16. # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
    17. # 所以,查找顺序:A --> B --> D --> C
    18. # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
    • 新式类(广度优先) 
      当类是新式类时,多继承情况下,会按照广度优先方式查找
     
    1. #新式类写法
    2. class N1(object):
    3. pass
    4. class N2(N1):
    5. pass

    新式类,实践测试

     
    1. class D(object):
    2. def bar(self):
    3. print('D.bar')
    4. class C(D):
    5. def bar(self):
    6. print('C.bar')
    7. class B(D):
    8. def bar(self):
    9. print('B.bar')
    10. class A(B, C):
    11. def bar(self):
    12. print('A.bar')
    13. a = A()
    14. a.bar()
    15. # 执行bar方法时
    16. # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
    17. # 所以,查找顺序:A --> B --> C --> D
    18. # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了

    经典类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错

    新式类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错

     

    1.2.4广度优先和深度优先

    下图,其深度优先遍历顺序为 1->2->4->8->5->3->6->7 
    广度优先 
    下图,其广度优先算法的遍历顺序为:1->2->3->4->5->6->7->8 
    深度优先

     

    1.2.5多态

    多态是面向对象的重要特性,简单点说:一个接口,多种实现。

     
    1. class F1:
    2. pass
    3. class S1(F1):
    4. def show(self):
    5. print('S1.show')
    6. class S2(F1):
    7. def show(self):
    8. print('S2.show')
    9. defFunc(obj):
    10. print(obj.show())
    11. s1_obj = S1()
    12. Func(s1_obj)
    13. s2_obj = S2()
    14. Func(s2_obj)
       





  • 相关阅读:
    bzoj1562: [NOI2009]变换序列
    bzoj2763: [JLOI2011]飞行路线
    有上下界网络流
    bzoj3211: 花神游历各国
    bzoj3668: [Noi2014]起床困难综合症
    bzoj2743: [HEOI2012]采花
    BZOJ 1787: [Ahoi2008]Meet 紧急集合
    BZOJ 1029 [JSOI2007]建筑抢修 贪心
    BZOJ 2748 音量调节
    BZOJ 3524: [Poi2014]Couriers 主席树
  • 原文地址:https://www.cnblogs.com/yangliheng/p/5857223.html
Copyright © 2020-2023  润新知