
多态性 鸭子类型 内置方法 反射 异常处理 断言 raise 自定义异常
发布日期:2021-05-08 03:56:52
浏览次数:24
分类:精选文章
本文共 5489 字,大约阅读时间需要 18 分钟。
多态性
多态:同一种事物有多种形态。
多态性:多态性指的是可以在不考虑对象具体类型的情况下直接使用对象。鸭子类型:强耦合思想,把不是同一种事物的用法统一在一起(归一的思想),使用者使用起来会更加方便
多态:同一种事物有多种形态class Animal: def say(self): print('动物是这么叫的',end='')class People(Animal): def say(self): super().say() print('嘤嘤嘤')class Dog(Animal): def say(self): super().say() print('汪汪汪') class Cat(Animal): def say(self): super().say() print('喵喵喵') 类里面的函数改成同一个名字say()obj1=People() # 调用类的接口改成变量名obj1obj2=Dog() # 调用类的接口改成变量名obj2obj3=Cat() # 调用类的接口改名变量名obj3obj1.say()-----># '动物是这么叫的嘤嘤嘤' People().say()obj2.say()-----># '动物是这么叫的汪汪汪' People().say()obj3.say()-----># '动物是这么叫的喵喵喵' People().say()# 甚至可以定制统一的接口接受传入的动物对象def animal_say(animal): # obj1 obj2 obj3当成参数传入 animal.say()
其实我们之前一直在接触这种多态的思想,不管是字符串,列表,字典,元祖,都可以测量长度。因为这些数据类型都有__len__方法。
len多态原理演示# "aaa".__len__()# [].__len__()# { }.__len__()def len(obj): return obj.__len__()print(len("aaa"))
我们可以强制规定子类使用父类的功能(通过定义抽象基类),也可以约定俗成靠程序员自我遵守统一的命名规范,下面我们简单示范一下两种情况。
代码演示import abcclass Animal(metaclass = abc.ABCMeta): # 导入adc模块强行统一标准,如果子类的代码不写成talk的函数名调用会直接报错 @abc.abstractmethod # 强制约束所有子类都得有这些功能 def talk(self): # 定义了抽象基类,给父类的功能添加装饰器后,就规定了子类定义名字相同的这些功能,如果子类没有,就会报错 pass注意:导入adc模块后的父类只能作为一个标准去定标准,不能再实例化去使用class Animal: def talk(self): passclass Dog(Animal): def talk(self): print("汪汪汪")class Cat(Animal): def talk(self): print("喵喵喵")class Pig(Animal): def talk(self): print("哼哼哼")obj1 = Dog()obj2 = Cat()obj3 = Pig()# 定制统一的接口接受传入的动物对象def talk(animal): animal.talk()
# 代码示范:靠程序员自觉性实现相同效果class Dog: def say(self): print('汪汪汪')class Cat: def say(self): print('喵喵喵')class Pig: def say(self): print('哼哼哼')
但其实我们完全可以不依赖于继承,只需要制造出外观和行为相同对象,同样可以实现不考虑对象类型而使用对象,这正是Python崇尚的“鸭子类型”(duck typing):“如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子”。比起继承的方式,鸭子类型在某种程度上实现了程序的松耦合度。
# 二者看起来都像文件,因而就可以当文件一样去用,然而它们并没有直接的关系class Txt: # Txt类有两个与文件类型同名的方法,即read和write def read(self): pass def write(self): passclass Disk: # Disk类也有两个与文件类型同名的方法:read和write def read(self): pass def write(self): pass
内置方法
class Foo: passobj = Foo() # obj是Foo的一个对象,也可以讲Foo是obj的一个实例print(isinstance(obj, Foo)) # isinstance 用来判断obj是不是Foo的一个实例print(isinstance([1, 2, 3], list)) # isinstance 用来判断[1,2,3]是不是Foo的一个实例print(issubclass(Foo, object)) # 判断Foo是否是object的子类__开头并且__结尾的属性会在满足某种条件下自动触发class People: def __init__(self, name, age): self.name = name self.age = age def __str__(self): # str用来控制对象显示打印结果的,str没有参数,返回值必须是str类型 return "%s %s" % (self.name, self.age)obj = People("nana", 18)print(obj) # print(obj._str_())class People: def __init__(self, name, age): self.name = name self.age = age self.f = open("a.txt", mode="rt", encoding="utf-8") def __del__(self): # 类的对象被删除后,会自动触发del的运行 self.f.close()obj = People("nana", 18)del objprint("=========end============")
反射
反射在类与对象里面全都通用
hasattr:判断对象是否拥有某个属性getattr: 获得对象中的某个属性 (查)setattr:将对象中某个属性设置为新的属性 (增,改。属性没有就增加,有就覆盖)delattr:删除对象中的某个属性 (删)
class People: country = "China" def __init__(self, name, age): self.name = name self.age = age def tell_info(self): print(self.name, self.age)obj = People("nana", 18) # 调用类传入参数("nana", 18)实例化到一个对象objprint(hasattr(obj, "country")) # hasattr判断能不能调用到obj.country,会先从对象里面去查看,找不到会从类里面去找res = getattr(obj, "country") # getattr取值obj.countryprint(res)method = getattr(obj, "tell_info") # getattr可以拿到obj与tell_info的绑定方法method()setattr(obj, "xxx", 111) # obj.xxx=111print(obj.xxx)delattr(obj, "name") # 删除obj里面self.nameprint(obj.name)
异常处理
什么是异常 异常是错误发生的信号, 程序一旦出错就会产生一个异常 如果该异常没有被处理,该异常就会抛出来,程序的运行也随即终止错误一般分为两种
1.语法错误 2.逻辑错误如何处理异常
语法错误->程序运行前就必须改正确 逻辑错误->针对可以控制的逻辑错误,应该直接在代码层面解决 针对不可以控制的逻辑错误,应该采用 try…except…可控的逻辑错误案例:age = input("age:").strip()if age.isdigit(): age = int(age) if age > 19: print("too big") elif age < 19: print("too small") else: print("you got it")else: print("输入的必须是数字")
try…except… 是一种异常产生之后的补救措施
# try...except...的完整语法print("start...")try: 被监测的代码块1 被监测的代码块2 被监测的代码块3 被监测的代码块4 被监测的代码块5except 异常的类型1 as e: 处理异常的代码except 异常的类型2 as e: 处理异常的代码except 异常的类型3 as e: 处理异常的代码except (异常的类型4,异常的类型5,异常的类型6)as e: 处理异常的代码except Exception: # Exception可以处理所有的异常,保证程序的正常运行 处理异常的代码else: 没有发生异常时要执行的代码finally: 无论异常与否,都会执行该代码,通常用来进行回收资源的操作print("end...")# 注意try可以只跟except,finally联用,但是try不能else联用
try…except…模拟不可控逻辑案例演示
案例1:print("start...")try: print(111) print(222) l = [11, 22, 33] l[100] print(333)except IndexError as e: # 异常处理对上了就显示异常提示信息,抛出异常后继续执行代码 print(e)print("end...")案例2:print("start...")try: print(111) print(222) l = [11, 22, 33] l[100] print(333)except KeyError as e: # 异常对不上会直接报错,不会继续执行代码,程序直接崩掉 print(e)print("end...")案例3:print("start...")try: print(111) print(222) l = [11, 22, 33] l[0] dic = { "k1": 111} dic["kkk"] print(333)except Exception as e: # except Exception可以抛出异常后,继续执行代码 print(e)else: # 没有发生异常时要执行的代码 print("else的代码")finally: # 无论异常与否,都会执行该代码,通常用来进行回收资源的操作 print("=====>finally的代码") print("end...")
断言 raise 自定义异常
断言代码呈现l = [111, 222]# if len(l) != 3:# raise Exception("必须达到三个值")assert len(l) == 3 # 判断条件是否成立,如果条件不成立抛出异常,不会再执行后续代码,一般适用于测试代码的时候,如果条件成立,assert就会当作不存在print("后续代码")raiseraise IndexError("索引错误") # 主动抛异常,自己指定规则的时候可以用raise制定异常自定义异常class Permissio(BaseException): def __init__(self, msg): self.msg = msgraise Permissio("权限错误") # 自己制定异常
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2025年03月25日 11时34分53秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
eclipse引用sun.misc开头的类
2021-05-08
firefox中angular2嵌套发送请求问题
2021-05-08
【mybatis3】调试/断点打印日志
2021-05-08
C++
2021-05-08
[CTFSHOW]PHP特性
2021-05-08
navigator对象
2021-05-08
关于EFI系统分区(ESP)你应该知道的3件事
2021-05-08
5.Mybatis复杂映射开发
2021-05-08
Servlet2.5的增删改查功能分析与实现------删除功能(四)
2021-05-08
环境配置 jdk_mysql_myeclipse8.6
2021-05-08
Session验证码的实现(2018-7-3)
2021-05-08
spring启动错误:Could not resolve placeholder
2021-05-08
日志写入xml上传ftp遇到的问题
2021-05-08
下载任意版本vmware对应的vmware tools
2021-05-08
将 github 中他人的 仓库 导入 码云中,从而 加快下载速度的 方式
2021-05-08
Java 类加载的过程 加载、验证、准备、解析、初始化
2021-05-08
JavaWeb---实现JavaBean来接收参数、请求转发、域对象
2021-05-08
瀚高数据库中 java代码类型与bit对应(APP)
2021-05-08
选择性估算器绕过行安全策略漏洞
2021-05-08
PostgreSQL中的触发器
2021-05-08