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]

授权

待补充

最新文章

  1. ASP.NET Core 源码阅读笔记(1) ---Microsoft.Extensions.DependencyInjection
  2. 附录E 安装Kafka
  3. fillStyle径向渐变
  4. 解决Unable to create new native thread
  5. MyBatis操作指南-与Spring集成(基于注解)
  6. Bat脚本实现MySQL数据库SQL文件备份
  7. Google File System翻译(转)
  8. canvas脏域问题纪录
  9. python之类私有成员
  10. Spring 简单入门实例
  11. L - Connections in Galaxy War - zoj 3261
  12. Coroutine,你究竟干了什么?
  13. Linux crontab定时执行任务命令格式与详细例子
  14. Nginx 开启gzip 压缩,实现基于域名的虚拟主机。
  15. 找出数组中最大值and索引
  16. java实现sftp客户端上传文件以及文件夹的功能
  17. 使用Webuploader大文件分片传输
  18. Linux基础命令---检查密码文件pwck
  19. 0 or 1(hdu2608)数学题
  20. 001 SpringMVC的helloWorld程序

热门文章

  1. jQuery简单日历插件版
  2. 【BZOJ4491】我也不知道题目名字是什么 [线段树]
  3. 两小时快速构建微信小程序
  4. 网络协议之HTTP协议
  5. 自己动手一步步安装Linux系统
  6. ES的优化布局
  7. C基础 读写锁中级剖析
  8. 排名函数row_number() over(order by)用法
  9. (转)函数后面加const--C++ const成员函数
  10. html,获取iframe的window,document,自定事件与iframe通信