Python开发基础-Day22反射、面向对象进阶
isinstance(obj,cls)和issubclass(sub,super)
isinstance(obj,cls)检查是否obj是否是类 cls 的对象,如果是返回True
class Foo(object):
pass
obj = Foo()
print(isinstance(obj, Foo))
issubclass(sub, super)检查sub类是否是 super 类的派生类,如果是返回True
class Foo(object):
pass
class Bar(Foo):
pass
issubclass(Bar, Foo)
反射
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。
python面向对象中的反射:通过字符串的形式操作对象相关的属性。而python中的一切事物都是对象,即都可以使用反射。
示例代码:
class Teacher:
school='jialidun'
def __init__(self,name,age):
self.name=name
self.age=age
def teach(self):
print('%s teach' %self.name)
通过字符串的方式判断是否存在一个属性:
t=Teacher('bob',18)
print(hasattr(Teacher,'name')) #False
print(hasattr(Teacher,'school')) #True
print(hasattr(Teacher,'teach')) #True
print(hasattr(t,'name')) #True
print(hasattr(t,'school')) #True
print(hasattr(t,'teach')) #True
通过字符串的方式获取一个属性:
print(getattr(Teacher,'school')) #获取到则返回属性的值
print(getattr(Teacher,'sdfad',None)) #获取不到返回None,如果不指定None那么抛出异常错误
通过字符串的方式设定一个属性:
setattr(Teacher,'sex','male') #设定Teacher类的属性sex='male'
setattr(t,'sex','female') #设定对象t对象的属性sex='female'
print(Teacher.__dict__)
print(t.__dict__)
通过字符串的方式删除一个属性:
delattr(Teacher,'sex')
delattr(t,'sex')
反射应用场景:用户交互
class Cmd:
def __init__(self,name):
self.name=name
def run(self):
while True:
cmd=input('>>>').strip()
if not cmd:continue
if hasattr(self,cmd): #判断这个类包含不包含输入的属性
func=getattr(self,cmd) #如果包含,获取该属性
func() #执行该属性(输入name会抛错提示字符串不能被调用,因为name是一个数据属性,而非函数属性)
else:
print('not valid func')
def ls(self):
print('ls function')
def pwd(self):
print('pwd function')
def cat(self):
print('cat function')
c=Cmd('bob')
c.run()
反射的好处
实现可插拔机制:可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,即可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
动态导入模块:基于反射当前模块成员
__str__方法
改变对象的字符串显示
class Teacher:
def __init__(self,name,age):
self.name=name
self.age=age
t=Teacher('bob',18)
print(t)
输出结果
<__main__.Teacher object at 0x0000020FC4DA9278> #########分割线君########### class Teacher:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return '<name:%s age:%s>' % (self.name, self.age)
t=Teacher('bob',18)
print(t) #t.__str__()
输出结果:类中的__str__函数的执行结果
<name:bob age:18>
__del__方法
在程序执行完了之后会自动执行的内容
class Foo:
def __init__(self,x):
self.x=x
def __del__(self):
print('执行__del__')
'''一般用来做一些关于对象执行完了之后剩下的垃圾的清理操作'''
f=Foo(10)
print('执行完了') 输出结果:先执行最后的print,没有代码了执行__del__函数
执行完了
执行__del__
删除对象后立即执行的内容
class Foo:
def __init__(self,x):
self.x=x
def __del__(self):
print('执行__del__')
'''做一些关于对象的清理操作'''
f=Foo(10)
del f #删除的时候也会执行del内容
print('执行完了') 输出结果:删除了f对象后执行了__del__后才执行最后的print
执行__del__
执行完了
item系列
以中括号的方式进行处理类似于:
l=['a','b','c']
dic={'a':1}
print(l[1])
print(dic['a'])
__getitem__、__setitem__、__delitem__
class Teacher:
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def __getitem__(self, item): #查询
# return getattr(self,item)
return self.__dict__[item]
def __setitem__(self, key, value): #设置
# setattr(self,key,value)
self.__dict__[key]=value
def __delitem__(self, key): #删除
# delattr(self,key)
self.__dict__.pop(key)
f=Teacher('bob',18,'male')
print(f.name) #f['name']
print(f['name']) #查询
f['name']='bob_nb' #设置
print(f.__dict__)
del f['name'] #删除
print(f.__dict__)
__len__方法
给对象提供len()统计方法
class Teacher:
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def __len__(self): #长度设置为10
return 10
f=Teacher('bob',18,'male')
print(len(f)) #输出10
其他方法(补充)
__setattr__,__delattr__,__getattr__方法
class Foo:
x=1
def __init__(self,y):
self.y=y
def __getattr__(self, item):
print('----> from getattr:你找的属性不存在')
def __setattr__(self, key, value): #限制赋值,无法对属性直接赋值,必须要对__dict__进行操作赋值
print('----> from setattr')
# self.key=value #这就无限递归了,任何赋值操作都会调用__setattr__的运行,所以....
# self.__dict__[key]=value #应该使用这种方式,操作字典可以赋值成功
def __delattr__(self, item):
print('----> from delattr')
# del self.item #无限递归了,同__setattr__方法的无限递归
self.__dict__.pop(item)
#__setattr__添加/修改属性会触发它的执行
f1=Foo(10)
f1.__setattr__('a',1) #不是直接操作字典,无法赋值
print(f1.__dict__) # 因为重写了__setattr__,凡是赋值操作都会触发它的运行,什么都不写,就是根本没赋值,除非直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__)
#__delattr__删除属性的时候会触发
f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a #删除的时候如果上面函数是del self.item,会无限递归
print(f1.__dict__) #__getattr__只有在使用点调用属性且属性不存在的时候才会触发
f1.xxxxxx
包装(对标准数据类型进行方法修改)
通过继承和派生的方式,进行修改源生数据类型的方法
class List(list): #继承list所有的属性,也可以派生出自己新的,比如append和mid
def append(self, p_object):
'派生自己的append:加上类型检查'
if not isinstance(p_object,int):
raise TypeError('must be int')
super().append(p_object)
@property
def mid(self):
'新增自己的属性'
index=len(self)//2
return self[index]
授权
待补充
Python开发基础-Day22反射、面向对象进阶的更多相关文章
- 还在用Alpine作为你Docker的Python开发基础镜像?其实Ubuntu更好一点
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_173 一般情况下,当你想为你的Python开发环境选择一个基础镜像时,大多数人都会选择Alpine,为什么?因为它太小了,仅仅只有 ...
- python基础-9.1 面向对象进阶 super 类对象成员 类属性 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理
上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...
- Python开发基础-Day17面向对象编程介绍、类和对象
面向对象变成介绍 面向过程编程 核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西.主要应用在一旦完成很少修改的地方,如linux ...
- python开发基础之语法基础
一.知识点 (一)python介绍 1.Python被设计成一种高可读性的语言,它大量地使用了英语单词作为关键字,不像其他语言使用标点符号构成复杂的语法结构. 2.Pyton是支持面向对象的,支持在对 ...
- Python开发基础-Day31 Event对象、队列和多进程基础
Event对象 用于线程间通信,即程序中的其一个线程需要通过判断某个线程的状态来确定自己下一步的操作,就用到了event对象 event对象默认为假(Flase),即遇到event对象在等待就阻塞线程 ...
- Python开发基础-Day23try异常处理、socket套接字基础1
异常处理 错误 程序里的错误一般分为两种: 1.语法错误,这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正 2.逻辑错误,人为造成的错误,如数据类型错误.调用方法错误等,这些解 ...
- Python全栈day26-27(面向对象进阶)
参考 http://www.cnblogs.com/linhaifeng/articles/6204014.html 1,什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访 ...
- Python学习之路10☞面向对象进阶
一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 class Foo(objec ...
- Python开发基础之Python常用的数据类型
一.Python介绍 Python是一种动态解释型的编程语言.Python它简单易学.功能强大.支持面向对象.函数式编程,可以在Windows.Linux等多种操作系统上使用,同时Python可以在J ...
随机推荐
- Redux Concepts
Redux解决数据通信复杂问题. Store 存储数据的地方,一个应用只有一个Store. State Store对象包含所有数据. Action 一个对象,表示View的变化. Action Cre ...
- 「6月雅礼集训 2017 Day10」perm(CodeForces 698F)
[题目大意] 给出一个$n$个数的序列$\{a_n\}$,其中有些地方的数为0,要求你把这个序列填成一个1到$n$的排列,使得: $(a_i, a_j) = 1$,当且仅当$(i, j) = 1$.多 ...
- 汕头市队赛SRM 20 T1魔法弹
T1 背景 “主角光环已经不能忍啦!” 被最强控制AP博丽灵梦虐了很长一段时间之后,众人决定联合反抗. 魂魄妖梦:“野怪好像被抢光了?” 十六夜咲夜:“没事,我们人多.” 然后当然是以失败告终了. 八 ...
- 消息队列之 ActiveMQ(山东数漫江湖)
简介 ActiveMQ 特点 ActiveMQ 是由 Apache 出品的一款开源消息中间件,旨在为应用程序提供高效.可扩展.稳定.安全的企业级消息通信. 它的设计目标是提供标准的.面向消息的.多语言 ...
- HDU 2199 二分
我们可以发现这个函数是单增的,那么这样二分就好了. 反思:刚转C++,不会用scanf读入实数.(scanf("%lf",&y)) //By BLADEVIL #inclu ...
- eCharts_基于eCharts开发的一个多图表页面
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- solaris如何启动ssh服务
先查看一下ssh服务状态:# svcs或# svcs | grep sshonline Aug_07 svc:/network/ssh:default 如需要关闭ssh服务(关闭完可以 svcs | ...
- 使用EL表达式需要注意的
1.表达式与Java无关,表达式都是以${开始,以}结束. 2.EL访问java变量不能直接访问,因为得不到数据,要访问数据,需要将其放到作用域中.而使用<%=java变量%>可以访问ja ...
- Python学习笔记 - day11 - Python操作数据库
MySQL的事务 MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关,MySQL的两种引擎如下: 1.MyISAM:不支持事务,用于只读程序提高性能 2.InnoDB:支持ACID ...
- Vue组件-组件的属性
在html中使用元素,会有一些属性,如class,id,还可以绑定事件,自定义组件也是可以的.当在一个组件中,使用了其他自定义组件时,就会利用子组件的属性和事件来和父组件进行数据交流. 比如,子组件需 ...