(1)isinstance(obj,cls)检查对象obj是否是类 cls 的对象,返回True和Flase
示例:
class People: country="china" def __init__(self,name): self.name=name def test(self): print("test") p=People("xuyaunyuan") print(p.name) print(isinstance(p,People))#判断对象P是不是类People的对象执行结果是:
xuyaunyuan True
(2)issubclass(sub, super)检查sub类是否是 super 类的派生类,返回True和Flase
示例:
class People: country="china" def __init__(self,name): self.name=name def test(self): print("test") class Student(People): def __init__(self,name,id): self.name=name self.id=id print(issubclass(Student,People))#检查Student类是否是 super 类(people类)的派生类执行结果是:
True
(1)反射的概念:主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。
(2)四个可以实现自省的函数(下列方法适用于类和对象,一切皆对象,类本身也是一个对象)
a、hasattr(object,name)——判断object中有没有一个name字符串对应的方法或属性
b、getattr(object,name)——获取属性
c、setattr(x, y, v)——设置属性
d、delattr(x, y)—— 删除属性
分别示例:
a、hasattr(object,name)——判断object中有没有一个name字符串对应的方法或属性
class People: country="china" def __init__(self,name): self.name=name def test(self): print("test") p=People("xuyaunyuan") #hasattr有没有 print(hasattr(p,"name"))#判断对象P有没有name属性 print("name" in p.__dict__)#等同于上面执行结果是:
True True
b、getattr(object, name, default=None)——获取属性
class People: country="china" def __init__(self,name): self.name=name def test(self): print("test") p=People("xuyaunyuan") #getattr#获取 print(getattr(p,"country"))#获取数据属性country print(getattr(p,"name"))执行结果是:
china xuyaunyuan
c、setattr(x, y, v)——设置属性
class People: country="china" def __init__(self,name): self.name=name def test(self): print("test") p=People("xuyaunyuan") #setattr设置setatttr(x指对象,y指属性,v指value值) setattr(p,"age",18) setattr(p,"sex","woman") print(p.__dict__)#查看是否设置成功执行结果是:
{'name': 'xuyaunyuan', 'age': 18, 'sex': 'woman'}
d、delattr(x, y)—— 删除属性
class People: country="china" def __init__(self,name): self.name=name def test(self): print("test") p=People("xuyaunyuan") #delattr#删除 delattr (p,"name") print(p.__dict__)#查看是否删除成功执行结果是:
{}
总结:
hasattr(obj,'属性') #obj.属性 是否存在getattr(obj,'属性') #获取obj.属性 不存在则报错getattr(obj,'属性','默认值') #获取obj.属性 不存在不会报错,返回那个默认值setattr(obj,'属性','属性的值') #obj.属性=属性的值delattr(obj,'属性') #del obj.属性
(3)反射当前模块的属性
关于文件的2种运行方式:把文件当脚本运行和把文件当做模块导入
a、关于导入其他模块,利用反射查找该模块是否存在某个方法
示例:
新建2个文件,分别取名为test.py和test1.py
import sys ##在test.py文件下定义一些名字 x=11#定义变量名x class People:#定义类名People def __init__(self): pass def s1():#定义函数名s1 print("s1") def s2():#定义函数名s2 print("s2") import test#在test1.py的文件下导入test模块 #在test1.py的文件下导入test模块 print(test)#打印导入的test模块 print(test.People)#打印类 test.s1()#运行函数s1 test.s2()#运行函数s2 print(test.x)#打印变量x执行结果是:
<module 'test' from 'C:\\Users\\Administrator\\PycharmProjects\\py_fullstack_s4\\day32-面向对象进阶\\模块导入\\test.py'> <class 'test.People'> s1 s2 11
b、在自己的文件内部查看自己的模块
this_module = sys.modules[__name__]#在自己的文件内查看自己的模块和绝对路径print(this_module)示例: import sys class Foo: pass def s1(): print('s1') def s2(): print('s2') this_module = sys.modules[__name__]#在自己的文件内查看自己的模块和绝对路径 print(this_module) print(hasattr(this_module, 's1'))#也可进行判断在this_module里面有没有s1 print(getattr(this_module, 's2'))#也可获取this_module里面的s2 this_module.s2()#运行s2函数 this_module.s1()#运行s1函数
执行结果是:
<module '__main__' from 'E:/飞秋/徐圆圆课程视频/Python fullstack s4 基础篇-day31/day31/test.py'> True <function s2 at 0x000000000282A8C8> s2 s1
(4)反射的好处(为什么要用反射)
好处一:实现可插拔机制
反射的好处就是,可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
示例:
新建2个文件,分别为客户端和服务端
在客户端定义如下:
class FtpClient: 'ftp客户端,但是还有没有实现具体的功能' def __init__(self,addr): print('正在连接服务器[%s]'