一.面向对象与面向过程分析

  1.print(len('123')) # 面向过程

   #清晰知道操作的功能,但不能明确操作的具体对象,需要传入参数.

  2.print('123'.__len__()) # 面向对象

   #清晰知道操作的对象,但不能确定具体的操作方法,需要.语法选择

二.接口思想

  接口:建立关联的桥梁,方便管理代码

  接口类: 用来定义功能的类,为继承它的子类提供功能

       该类的功能方法一般不需要有实现体

      实现体由继承它的子类自己去实现

  # 提供所有宠物应该有的功能

  class PetInterface:

    def close_master(self):pass

  # 提供所有看门应该有的功能

  class WatchInterface:

    def watch_door(self):pass

  # 没有继承PetInterface,WatchInterface的Dog就是普通Dog类

  # 但继承了PetInterface,该Dog就可以作为宠物狗,同理,继承WatchInterface就可以作为看门狗

  class Dog(PetInterface,WatchInterface):

    def jiao(self):pass

    def chi(self):pass

    def pao(self):pass

    # 在类中一定要重写接口的方法

    def close_master(self): # 写功能体

    def watch_door(self): # 写功能体

三.抽象父类

  抽象父类:拥有抽象方法(子类共有的方法,但父类不能有具体的实现体)的父类

  抽象方法:方法名是具体的,但实现体是抽象的(需要在子类中重写来具象化)

  注意: 有抽象方法的父类不能被实例化(假设能被实例化,就可以调用自己的抽象方法,没有任何意义)

  # 实现抽象父类的语法(abc)

  import abc # abstract base class

  class Sup(metaclass=abc.ABCMeta):

    #抽象父类中的抽象方法,在继承它的子类中必须有自己的实现体

    #       -- 抽象父类中的抽象方法实现体没有意义,实现或不实现都是pass填充

    @abc.abstractmethod

    def func(self):pass

  class Sub(Sup):

    def func(self):

    #必须重写父类的抽象方法

  案例:

  import abc

  class Quan(metaclass=abc.ABCMeta):

    def __init__(self,name):

      self.name = name

    # 共有方法,子类继承就可以了

    def run(self):

      print(self.name + 'running')

    # 抽象方法:子类必须重写

    @abc.abstractmethod

    def chi(self):pass

    @abc.abstractmethod

    def jiao(self):pass

  class Dog(Quan):

    def kanmen(self):

      print(self.name + '看门')

    def chi(self):

      super().chi() # 不执行

      print(self.name + '狗粮')

    def jiao(self):

      print('汪汪汪')

  class Wolf(Quan):

    def bulie(self):

      print(self.name + '捕猎') 

    def chi(self):

      print(self.name + '肉')

    def jiao(self):

      print('嗷嗷嗷')

  dog = Dog('狗')

  wolf = Wolf('狼')

  dog.jiao() # 汪汪汪

  wolf.jiao() # 嗷嗷嗷

  dog.run() # 狗 running

  wolf.run() # 狼 running

  了解:

    # 抽象的类方法   

  import abs
  class Sup(metaclass=abc.ABCMeta):
    @classmethod
    @abc.abstractmethod
    def func(cls): pass

  class Sub(Sup):
    @classmethod
    def func(self):
      # 必须重写父类的抽象方法

四.多态

  多态:对象的多状态 - 父类对象的多种(子类对象)状态

  import abc

  class People(metaclass=abc.ABCMeta):

    def __init__(self,name):

      self.name = name

    @abc.abstractmethod

    def speak(self):pass

  class Chinese(People):

    def speak(self):

      print('说中国话')

  class Engiand(People):

    def speak(self):

      print('说英国话')

  if __name__ == '__main__':

    # 多态的体现:功能或是需求,需要父类的对象,可以传入父类对象或任意子类对象

    #  一般都是规定需要父类对象,传入子类对象

    def ask_someone(obj):

      print('让%s上台演讲'%obj.name) # 父类提供,自己直接继承

      obj.speak() # 父类提供,只不过子类重写了

    ch = Chinese('王大锤')

    en = England('Tom')

    # 传入Chinese|England均可以,应为都是People的一种状态(体现方式)

    ask_someone(ch) # 让王大锤上台演讲 说中国话

    ask_someone(en) # 让Tom上台演讲 说英国话

    # 传入str不可以,因为str的对象没有name和speak

    # s = str('')

五.鸭子类型

  需求:需要一个对象,该对象有name属性和speak方法,就可以作为一种状态的体现被传入

  def ask_someone(obj):

    print('让%s上台演讲'%obj.name)

    obj.speak()

  # 鸭子类型

  # 1.先规定:有什么属性及什么方法的类的类型叫鸭子类型

  # 2.这些类实例化出的对象,都称之为鸭子,都可以作为需求对象的一种具体体现

  class A:

    # 能有自己特有的属性和方法,可以和B完全不一样

     但必须有鸭子类型规定的属性和方法,不然就不是鸭子类型

    def __init__(self,name):

      self.name = name

    def speak(self):

      print('说AAA')

  class B:

    # 能有自己特有的属性和方法,可以和B完全不一样

     但必须有鸭子类型规定的属性和方法,不然就不是鸭子类型

    def __init__(self,name):

      self.name = name

    def speak(self):

      print('说BBB')

  ask_someone(B('B')) # 让B上台演讲 说BBB

六.格式化方法与析构方法

  class A:

    def __init__(self,name,age):

      self.name = name

      self.age = age

    # 格式化方法:在外界打印该类对象是被调用

    # 格式化外界直接打印该类对象的字符串表示结果

    def __str__(self):

      # return 'abc' # 外界打印A类的对象,都打印字符串 abc

      # return super().__str__() # 系统默认的在父类中返回的是对象存放的地址信息

      return '<name:%s | age:%s>' % (self.name, self.age)

    # 根据对象实际的属性格式化具体的输出内容

    #析构方法:在对象被消耗的那一刹那被调用,在被消耗前可以做一些事情

    def __del__(self):

      # del会在self代表的对象被消耗的时候被调用

      # 我们可以在析构函数中释放该对象持有的其他资源

      # 或者将一些持有资源持久化(保存到文件或者数据库中)

      del self.name # 也可以将name存起来

  a = A('老王',88)

  print(a,type(a)) # <name:老王 | age:88> <class '__main__.A'>

  print('文件马上执行完毕,a就会被销毁')

  了解:

  class B:

    # 了解:对象.语法的内部实现

    def __setattr__(self,key,value):

      self.__dict__[key] = value # 系统默认实现,在名称空间添加名字

      # self.__dict__[key] = value.lower() # 可以自定义处理一些内容

    # 了了解:将对象添加属性的方式可以同字典形式

    def __setitem__(self,key,value)

      self.__dict__[key] = value

  b = B()

  # 设置

  b.name = 'BBB' # 内部走的是__setattr__

  b['age'] = 18 # 内部走的是__setitem__

  # 访问

  print(b.name)

  print(b.age)

七.反射

  # 反射:通过字符串与类及类的对象的属性(方法)建立关联

  class A:

    num = 10

  print(hasattr(A,'num'))

  res = getattr(A,'num','默认值')

  print(res)

  delatter(A,'num')

  print(setattr(A,'tag',10))

  # 类的属性类来操作

  class B:

    def __init__(self,name)

      self.name = name

  print(hasattr(b,'name'))

  b = B('BBB')

  print(hasattr(b, 'name'))
  print(getattr(b, 'name', '对象的属性类不能获取'))
  delattr(b, 'name')
  print(setattr(b, 'age', 18))
  # 对象的属性对象来操作

  class C:

    def fn(self):

      print('fn')

    @classmethod

    def func(cls):

      print('func')

  fn = getattr(C,'fn')

  c = C()

  fn(c) # 类获取对象方法调用时传入具体的对象

  obj_fn = getattr(c,'fn')

  obj_fn() # 对象获取对象方法调用时不用传参

  func = getattr(C,'func')

  func() # 类获取类方法调用时不需要传入参数

八.异常处理

  程序运行时的错误
  程序中的异常处理机制:
  1.程序中的所有异常都会被处理
  2.程序中的所有异常都需要手动处理
  3.如果没有手动处理异常,异常会交给Python解释器处理
-- 处理的方式就是打印异常信息,并停止接收器   异常信息的三部分:
  1.异常的追踪信息:提示错误位置
  2.异常的类型:告知处理异常应该捕获什么类型
  3.异常的内容:告知错误信息   处理异常的语法:
  '''
  try:
   # 会出现异常的代码块
  except 异常类型 as 异常别名:
  # 异常处理逻辑
  else:
  # 没有出现异常会执行该分支
  finally:
  # 无论是否出现异常都会执行该分支
  '''   try:
  print(adsdasadsdasadsdas)
  except NameError as e:
  print('异常信息:', e)
  else:
  print('被检测的代码块正常')
  finally:
  print('异常是否出现都会执行该分支')
  print('end')
  1.异常语法详解

    将可能出现异常的代码放在try分支进行检测
      -- 如果不出现异常,正常执行内部所有代码
      -- 如果出现异常会进入except分支

    part1
    # 建议大家对异常处理时,一次只处理一个异常
    try:
      print(asdsdsdsdsdsdsdsdsdsdsdsdsd) # NameError
    except NameError: # except 后跟异常类型,如果不需要查看异常信息,可以省略异常信息
      print('出现了NameError异常')

    try:
      ls = [1, 2, 3, 4, 5]
      print(ls[10]) # IndexError
    except IndexError as e: # 如果想知道异常信息,用别名接收
      print('出现了IndexError异常: %s' % e)

    part2
    # 如果无法避免一句话或是一个完整的代码结构会出现多个可能的异常,需要在一个try中提供多个except
    ls = [1, 2, 3, 4, 5]
    ls = (1, 2, 3, 4, 5, 6)
    try:
      # print(ls[5]) # IndexError
      # ls.append(10) # AttributeError
    except IndexError as e:
      # print('出现了IndexError异常: %s' % e)
    except AttributeError as e:
      # print('出现了AttributeError异常: %s' % e)
    try:
      print(ls[5]) # IndexError
      ls.append(10) # AttributeError
    except (AttributeError, IndexError) as e:
      print('出现了异常: %s' % e)

    part3
    # 3.有些异常提前无法明确,或是压根没有明确的必要,可以捕获异常的父类异常
    ls = [1, 2, 3, 4, 5]
    ls = (1, 2, 3, 4, 5, 6)
    try:
      print(ls[5]) # IndexError
      ls.append(10) # AttributeError
    except Exception as e: # 可以通过多态的应用,捕获父类,只要抛出的是该父类的子类异常,均可以被捕获
      print('出现了异常: %s' % e)

    # BaseException:所有异常的基类 | Exception:常规错误的基类

    part4
    # 4.了了解 - try语法的else分支:当try检测的代码块没有出现异常,才会走else分支
    try:
      print(aaaa)
    except Exception as e:
      print('出现了异常', e)
    else:
      print('没有异常')

    part5
    # 5.finally:无论是否出现异常都会执行该分支
    try:
      f = open('1.txt', 'w', encoding='utf-8')
      f.write(b'123')
    except Exception as e:
      print('出现了异常', e)
    finally:
      print('无论是否出现异常都会执行该分支')
      f.close() # 文件只要打开,不管操作是否出现异常,都需要释放文件资源  

  2.自定义异常

    # 自定义异常的目的:想抛一个有意义的异常,但这个异常系统没有提供,自定义一个
    class PeopleNameError(Exception): # Exception | BaseException
      # pass
    # 可以通过__init__明确外界的错误信息接收给那个属性
    # 再在__str__中格式化外界捕获异常,打印异常信息的格式
      def __init__(self, msg):
        self.msg = msg
      def __str__(self):
        return 'PeopleNameError: ' + self.msg

    def get_name():
    name = input('name: ')
    if 'sb' in name.lower():
      raise PeopleNameError('人名不能有敏感词汇')
    return name

    try:
      print(get_name())
    except PeopleNameError as e:
      print(e) # PeopleNameError: 人名不能有敏感词汇

  3.断言

    num = int(input('num: '))
    assert num < 0 # 断言:只有满足断言条件,程序才能往下执行,反之抛出异常
    print(abs(num))

												

DAY 25多态、反射、异常处理的更多相关文章

  1. day 25 面向对象之接口、抽象类、多态、异常处理、反射、断言

    复习 '''继承​1.父类:在类后()中写父类们class A:passclass B:passclass C(A, B):pass​2.属性查找顺序:自己 -> ()左侧的父类 -> 依 ...

  2. 类的特殊成员&反射&异常处理

    类的特殊成员 1.__doc__表示类的描述信息 class Foo(object): """ 描述类信息,这是用于看片的神奇 """ de ...

  3. 多态与异常处理ppt作业

    1.请阅读并运行AboutException.java示例,然后通过后面的几页PPT了解Java中实现异常处理的基础知识. 答:1.抛出异常 当程序发生异常时,产生一个异常事件,生成一个异常对象,并把 ...

  4. Day 25 多态.

    一.多态的概念 多态指的是一类事物有多种形态.动物有多种形态:人,狗,猪 from abc import ABCMeta,abstractmethod class Animal(metaclass=a ...

  5. python的继承多态以及异常处理

    1.单继承 # 动物类 class Animal(object): def __init__(self, name): self. __name = name def run(self): print ...

  6. JAVA 多态和异常处理作业——动手动脑以及课后实验性问题

    1.  阅读以下代码(CatchWho.java),写出程序运行结果: 1)  源代码 public class CatchWho { public static void main(String[] ...

  7. java多态与异常处理——动手动脑

    编写一个程序,此程序在运行时要求用户输入一个 整数,代表某门课的考试成绩,程序接着给出“不及格”.“及格”.“中”.“良”.“优”的结论. 要求程序必须具备足够的健壮性,不管用户输入什 么样的内容,都 ...

  8. java-08多态与异常处理

    1.运行以下代码: public class ParentChildTest { public static void main(String[] args) { Parent parent=new ...

  9. java练习——多态与异常处理

    1.   上面的程序运行结果是什么? 2.   你如何解释会得到这样的输出? parent = chlid; 所以child中的方法被赋予parent,所以用child方法输出了child的成员变量: ...

随机推荐

  1. How to Preloading content with rel preload

    The preload value of the <link> element's rel attribute allows you to write declarative fetch ...

  2. 浅析MySQL InnoDB的隔离级别

    MySQL InnoDB存储引擎中事务的隔离级别有哪些?对应隔离级别的实现机制是什么? 本文就将对上面这两个问题进行解答,分析事务的隔离级别以及相关锁机制. 隔离性简介 隔离性主要是指数据库系统提供一 ...

  3. Cache Aside Pattern

    Cache Aside Pattern 即旁路缓存是缓存方案的经验实践,这个实践又分读实践,写实践 对于读请求 先读cache,再读db 如果,cache hit,则直接返回数据 如果,cache m ...

  4. SQL注入检测方法

    private bool CheckParams(params object[] args){ string[] Lawlesses={"=","'"}; if ...

  5. Java里面使用Date.compareTo比较时间

    DateFormat dateFormat = DateFormat.getDateInstance(); Date oldTime = dateFormat.parse("2019-04- ...

  6. mySQL简单操作(三)

    1.事务 (1)ACID 原子性(不可分割性)automicity 一致性 consistency 隔离性 isolation 持久性 durability (2)事务控制语句 begin/start ...

  7. linux执行jmeter脚本解决响应数据为空

    Linux服务器用命令执行了jmeter脚本,在本地查看结果时发现结果树种的“请求.响应数据”都显示为空,有错误日志中也看不出所以然,请看演示! 1 ,先执行脚本:执行成功(...end of run ...

  8. Vue PC后台系统组件大全

    1.https://vue.ant.design/ 2.http://element-cn.eleme.io/#/zh-CN 3.https://www.iviewui.com/ 4.https:// ...

  9. vector内存回收

    1. vector所有的内存相关问题都可以归结于它的内存增长策略.vector有一个特点就是:内存空间只会增长不会减少.vector有两个函数,一个是capacity(),返回对象缓冲区(vector ...

  10. linux启动httpd服务出现 Could not reliably determine the server`s fully qualified domain name.

    安装好apache启动httpd服务时,出现httpd: Could not reliably determine the server's fully qualified domain name,  ...