day 25 二十五、抽象类、多态、鸭子、反射、异常处理
一、接口思想
1、接口:建立关联的桥梁,方便管理代码
python中没有接口语法
def jiao(): pass
def chi(): pass
def pao(): pass # 清晰知道操作的功能,但不明确操作的具体对象
print(len(''))
# 清晰最大操作的对象,但不明确具体的操作方法
print(''.__len__())
2、接口类:
用来定义功能的类,为继承它的子类提供功能的,该类的功能方法一般不需要有实现体,实现体有继承它的子类自己去实现
class PetInterface:
def close_master(self): pass class WatchInterface:
def watch_door(self): pass class Dog(PetInterface, WatchInterface):
def jiao(self): pass def chi(self): pass def pao(self): pass # 一定要重写接口的方法
pass class Cat(PetInterface, WatchInterface): pass
二、抽象类思想
抽象父类:拥有抽象方法(子类共有的方法,但是父类不能有具体的实现体)的父类
抽象方法:方法名是具体的,但是实现体是抽象的(在子类中重写来具象化)
# python中借助abc来实现抽象父类
import abc # abstract base class
class Quan(metaclass=abc.ABCMeta):
def __init__(self, name):
self.name = name
def run(self):
print(self.name + 'running') # 抽象父类中的抽象方法,在继承它的子类中必须有自己的实现体
# -- 抽象父类中的抽象方法实现体就没有意义,实现与不实现都是pass填充
@abc.abstractmethod
def chi(self):
# print(self.name + '肉')
pass
@abc.abstractmethod
def jiao(self):
# print('汪汪汪')
pass @classmethod
@abc.abstractmethod
def fn(cls): pass class Dog(Quan):
@classmethod
def fn(cls): pass def kanmen(self):
print(self.name + '看门')
def chi(self):
super().chi()
print(self.name + '吃狗粮')
def jiao(self):
print('汪汪汪') class Wolf(Quan):
@classmethod
def fn(cls): pass 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
dog.chi() # 来福吃狗粮
wolf.chi() # 常委吃肉
三、多态
1、定义:对象的多种状态 - 父类对象的多种(子类对象)状态
2、多态的体现:
功能或是需求,需要父类的对象,可以传入父类对象或任意子类对象均可以
注:一般都是规定需要父类对象,传入子类对象
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 England(People):
def speak(self):
print('说英国话') if __name__ == '__main__':
# 多态的体现:功能或是需求,需要父类的对象,可以传入父类对象或任意子类对象均可以
# 注:一般都是规定需要父类对象,传入子类对象
def ask_someone(obj):
print('让%s上台演讲' % obj.name) # 父类提供,自己直接继承
obj.speak() # 父类提供,只不过子类重写了 ch = Chinese('王大锤')
en = England('Tom') ask_someone(ch) # 让王大锤上台演讲
# 说中国话 ask_someone(en) # 让Tom上台演讲
# 说英国话
四、鸭子类型
1、定义:
①先规定:有什么属性及什么方法的类的类型叫鸭子类型
②这些类实例化出的对象,都称之为鸭子,都可以作为需求对象的一种具体体现
class Test:
def __init__(self, name):
self.name = name
def speak(self):
print('说鸟语') if __name__ == '__main__':
def ask_someone(obj):
print('让%s上台演讲' % obj.name) # 需要一个对象,这个对象需要什么特点,有name,有speak,
obj.speak() # 那就制定一个规则,只要有一个对象,它有name属性,speak方法,都叫鸭子
# 规定的规则能随意改变,需要一个什么样的对象,有这样特征的都叫鸭子
test = Test('鸭子')
# 规定一个对象有什么属性和方法,能提供该属性和方法的对象都叫鸭子
ask_someone(test) # 让鸭子上台演讲
# 说鸟语
2、例子
# 例:
# 需求:需要一个对象,该对象有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('说AAAA') class B:
# 能有自己特有的属性和方法,可以和A完全不一样,但是必须有鸭子类型规定的属性和方法,不然就不是鸭子类型
def __init__(self, name):
self.name = name def speak(self):
print('说BBBB') ask_someone(B('B')) # 让B上台演讲
# 说BBBB
五、格式化和析构方法
1、应用:
class A:
def __init__(self, name, age):
self.name = name
self.age = age # ①格式化方法:在外界打印该类对象是被调用
# 格式化外界直接打印该类对象的字符串表示结果
def __str__(self): 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'> import time
time.sleep(3) print('文件马上执行完毕,a就会被销毁')
2、了解:
class B:
# 了解:对象.语法的内部实现
def __setattr__(self, key, value):
# print(key, value)
b.__dict__[key] = value
# b.__dict__[key] = value.lower()
# b.__dict__['xyz'] = 'XYZ' # 了了解:将对象添加属性的方式可以同字典形式
def __setitem__(self, key, value):
self.__dict__[key] = value b = B()
b.name = 'BBB' # == b.__dict__['name'] = 'BBB'
print(b.name) # BBB b['age'] = 18
print(b.age) # 18 # 访问还是通过.语法访问
六、反射(*****)
1、定义:通过字符串与类和对象的属性(方法)建立关联
2、应用:
class People:
country = "China" def __init__(self, name):
self.name = name def tell(self):
print('%s is aaa' % self.name) obj = People('egon') # 1、hasattr(判断'country'是否在People的名称空间里)
print(hasattr(People, 'country')) # True # 'country'是否在People的名称空间里
print('country' in People.__dict__) # True # 不同的两种方法 print(hasattr(obj, 'name')) # True
print(hasattr(obj, 'country')) # True
print(hasattr(obj, 'tell')) # True # 2、getattr(查找)
x = getattr(People, 'country') # China
print(x)
x = getattr(People, 'country1',None)
print(x) # None f = getattr(obj, 'tell', None)
print(f == obj.tell) # True
f() # egon is aaa
obj.tell() # egon is aaa # 3、setattr(增值)
People.x = 111
setattr(People, 'x', 111)
print(People.x) # obj.age = 18
setattr(obj, "age", 18)
print(obj.__dict__) # {'name': 'egon', 'age': 18} # 4、delattr(删值)
delattr(People, "country") # ==del People.country
print(People.__dict__) # 从People的名称空间中删除了'country' delattr(obj, "name") # ==del obj.name
print(obj.__dict__) # {} # 删除obj里的’name’后,obj中的名称空间为空
补充:
①__getattr__:在对象获取它没有的属性和方法的时候自动触发
②__setattr__:在对象点属性设置属性值的时候自动触发
class Demo(object):
def __init__(self,name):
self.name = name def __getattr__(self, item):
print('这个对象想获取一个它没有的属性>>>:',item)
return 123 def __setattr__(self, key, value):
print(key, value) obj = Demo('jason')
obj.password = ''
print(obj.name)
print(obj.yyy) # 结果为
# name jason
# password 123
# 这个对象想获取一个它没有的属性>>>: name
#
# 这个对象想获取一个它没有的属性>>>: yyy
#
3、小练习:
class Foo:
def run(self):
while True:
cmd = input('cmd>>: ').strip()if hasattr(self, cmd):
func = getattr(self, cmd)
func()
def download(self):
print('download....') def upload(self):
print('upload...') obj=Foo()
obj.run()
# 结果为
cmd>>: download
download....
cmd>>: upload
upload...
4、总结
# 总结:
# 类的属性用类来操作
# 对象的属性用对象来操作
# 方法建议使用类来操作,得到的方法调用时
# -- 对象的方法要传入具体的对象
# -- 类的方法不需要传入参数 class C:
def fn(self):
print('fn') @classmethod
def func(cls):
print('func') fn = getattr(C, 'fn')
c = C()
fn(c) # fn func = getattr(C, 'func')
func() # func
day 25 二十五、抽象类、多态、鸭子、反射、异常处理的更多相关文章
- 二十五. Python基础(25)--模块和包
二十五. Python基础(25)--模块和包 ● 知识框架 ● 模块的属性__name__ # my_module.py def fun1(): print("Hello& ...
- C#学习基础概念二十五问
C#学习基础概念二十五问 1.静态变量和非静态变量的区别?2.const 和 static readonly 区别?3.extern 是什么意思?4.abstract 是什么意思?5.internal ...
- WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇]
原文:WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇] 在[WS标准篇]中我花了很大的篇幅介绍了WS-MEX以及与它相关的WS规范:WS-Policy.WS-Tra ...
- 策略模式 Strategy 政策Policy 行为型 设计模式(二十五)
策略模式 Strategy 与策略相关的常见词汇有:营销策略.折扣策略.教学策略.记忆策略.学习策略.... “策略”意味着分情况讨论,而不是一概而论 面对不同年龄段的人,面对不同的商品,必然将会 ...
- 使用Typescript重构axios(二十五)——文件上传下载进度监控
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 学习笔记:CentOS7学习之二十五:shell中色彩处理和awk使用技巧
目录 学习笔记:CentOS7学习之二十五:shell中色彩处理和awk使用技巧 25.1 Shell中的色彩处理 25.2 awk基本应用 25.2.1 概念 25.2.2实例演示 25.3 awk ...
- Bootstrap <基础二十五>警告(Alerts)
警告(Alerts)以及 Bootstrap 所提供的用于警告的 class.警告(Alerts)向用户提供了一种定义消息样式的方式.它们为典型的用户操作提供了上下文信息反馈. 您可以为警告框添加一个 ...
- VMware vSphere 服务器虚拟化之二十五 桌面虚拟化之终端服务池
VMware vSphere 服务器虚拟化之二十五 桌面虚拟化之终端服务池 终端服务池是指由一台或多台微软终端服务器提供服务的桌面源组成的池.终端服务器桌面源可交付多个桌面.它具有以下特征: 1.终端 ...
- Bootstrap入门(二十五)JS插件2:过渡效果
Bootstrap入门(二十五)JS插件2:过渡效果 对于简单的过渡效果,只需将 transition.js 和其它 JS 文件一起引入即可.如果你使用的是编译(或压缩)版的bootstrap.js ...
随机推荐
- Java z 404
problem: relative 与absolute 绝对和相对定位 为什么缩放页面里会有离开的情况 为什么a链接里与文字无法对齐 这么多代码为什么没有最好 用最简单的代码去执行一个相应的命令 实现 ...
- 51nod 1035 最长的循环节
正整数k的倒数1/k,写为10进制的小数如果为无限循环小数,则存在一个循环节,求<=n的数中,倒数循环节长度最长的那个数,假如存在多个最优的答案,输出所有答案中最大的那个数. 1/6= 0.1( ...
- pythonのsimple_tag
当我们需要在页面种直接调用py文件中的某些方法时,我们就要用到simple_tag.具体步骤如下: 1.在某个app下创建templatetags文件夹,切记该名称是不可以改变的. 2.在该文件夹下创 ...
- 20165221-week2课上测试补做
week2-课上测试补做 测试一: 参考附图代码,编写一个程序 "week0201学号.c",判断一下你的电脑是大端还是小端. 提交运行结果"学号XXXX的笔记本电脑是X ...
- Lua中的协同程序
[前言] 协同程序与线程差不多,也就是一条执行序列,拥有自己独立的栈.局部变量和指令指针,同时又与其它协同程序共享全局变量和其它大部分东西.从概念上讲,线程与协同程序的主要区别在于,一个具有多个线程的 ...
- 微信小程序-制作简易豆瓣笔记
demo截图: 图书: 电影: 共工欲善其事,必先利其器: 小程序编辑器下载地址 : https://mp.weixin.qq.com/debug/wxadoc/dev/dev ...
- upgrade openssl
01 OpenSSL version wiki:https://en.wikipedia.org/wiki/OpenSSL 02 Using TLS1.3 With OpenSSL https:// ...
- windows生成库文件
库文件的生成,包括静态库lib与动态库dll,需要改变编译输出的生成命令,可以一开始生成对应的库工程(或者在工程属性->常规->配置类型更改). 附基本对应命令: gcc –c -L .o ...
- thinkpad 睡眠唤醒后热键功能正常,但屏幕无法显示状态/进度条/图标
由于博主比较习惯笔记本开盖即用,合盖即走,不大习惯开机关机(毕竟SSD速度杠杠滴^_^).可是发现笔记本长时间睡眠乃至休眠唤醒后,使用thinkpad热键,虽然可以调节,但屏幕不显示调节状态了.解决步 ...
- (转)http authorization 基本认证
转:https://www.cnblogs.com/chenrong/articles/5818498.html http协议是无状态的, 浏览器和web服务器之间可以通过cookie来身份识别. 桌 ...