DAY 25多态、反射、异常处理
一.面向对象与面向过程分析
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多态、反射、异常处理的更多相关文章
- day 25 面向对象之接口、抽象类、多态、异常处理、反射、断言
复习 '''继承1.父类:在类后()中写父类们class A:passclass B:passclass C(A, B):pass2.属性查找顺序:自己 -> ()左侧的父类 -> 依 ...
- 类的特殊成员&反射&异常处理
类的特殊成员 1.__doc__表示类的描述信息 class Foo(object): """ 描述类信息,这是用于看片的神奇 """ de ...
- 多态与异常处理ppt作业
1.请阅读并运行AboutException.java示例,然后通过后面的几页PPT了解Java中实现异常处理的基础知识. 答:1.抛出异常 当程序发生异常时,产生一个异常事件,生成一个异常对象,并把 ...
- Day 25 多态.
一.多态的概念 多态指的是一类事物有多种形态.动物有多种形态:人,狗,猪 from abc import ABCMeta,abstractmethod class Animal(metaclass=a ...
- python的继承多态以及异常处理
1.单继承 # 动物类 class Animal(object): def __init__(self, name): self. __name = name def run(self): print ...
- JAVA 多态和异常处理作业——动手动脑以及课后实验性问题
1. 阅读以下代码(CatchWho.java),写出程序运行结果: 1) 源代码 public class CatchWho { public static void main(String[] ...
- java多态与异常处理——动手动脑
编写一个程序,此程序在运行时要求用户输入一个 整数,代表某门课的考试成绩,程序接着给出“不及格”.“及格”.“中”.“良”.“优”的结论. 要求程序必须具备足够的健壮性,不管用户输入什 么样的内容,都 ...
- java-08多态与异常处理
1.运行以下代码: public class ParentChildTest { public static void main(String[] args) { Parent parent=new ...
- java练习——多态与异常处理
1. 上面的程序运行结果是什么? 2. 你如何解释会得到这样的输出? parent = chlid; 所以child中的方法被赋予parent,所以用child方法输出了child的成员变量: ...
随机推荐
- Parco_Love_String
二维的kmp直接搞出来emmm, 后缀自动机都没这个快(本弱鸡不会后缀自动机) #include <bits/stdc++.h> using namespace std; #define ...
- spring-springmvc-jdbc小案例
此案例是为ssm作铺垫的. 创建一个银行账户和基金账户,然后通过银行账户购买基金.由spring.springmvc.spring自带的c3p0实现. 废话不多说.如下 涉及到的 jar包(多了): ...
- 关于Linux目录结构的理解
dUI与刚接触Linux的学习者来说,那么多的根下目录足够让我们头疼不已,如下图: 那么对于初学者来说,我们首要了解的是哪些目录呢? 就是这个标黄绿色的tmp目录,此目录是一个存放临时文件夹的目录( ...
- 【论文速读】Pan He_ICCV2017_Single Shot Text Detector With Regional Attention
Pan He_ICCV2017_Single Shot Text Detector With Regional Attention 作者和代码 caffe代码 关键词 文字检测.多方向.SSD.$$x ...
- sitecore开发入门之如何在代码中获取SITECORE图像URL
using Sitecore; using Sitecore.Data.Items; using Sitecore.Resources.Media; public string GetUrl() { ...
- Windbg程序调试系列3-线程阻塞问题
上一篇博文给大家分享了使用Windbg分析内存泄露问题: Windbg程序调试系列2-内存泄露问题 本篇我们继续跟大家分享,如何分析解决线程阻塞问题. 从根本上讲,线程阻塞属于程序Hang的一种,其表 ...
- Mysql 导入文件提示 --secure-file-priv option 问题
MYSQL导入数据出现:The MySQL server is running with the --secure-file-priv option so it cannot execute this ...
- 20175208『Java程序设计』课程 结对编程练习_四则运算
20175208 结对编程练习_四则运算(第一周) 结对成员:20175208张家华,20175202葛旭阳 一.需求分析: 实现一个命令行程序,要求: (1)自动生成指定数量的小学四则运算题目(加. ...
- get 和 post 请求的区别,一个不错的链接
https://www.cnblogs.com/logsharing/p/8448446.html
- github一些事
我的个人github地址是:https://github.com/BUGDuYu 我们开发团队小组的github地址是: https://github.com/APPdoctrine 资源推荐: gi ...