使用对象反射
obj . 属性名
obj . 方法名()
可以直接适用对象的方法和属性
当我们只有字符串数据类型的内容的时候
可以使用
getattr(对象名,'方法名')() 来调用方法
getattr(对象名,'属性名') 来调用属性
1.使用对象反射 class Manager: # 管理员用户 def __init__(self,name): self.name = name def create_course(self): # 创建课程 print('in Manager create_course') def create_student(self): # 给学生创建账号 print('in Manager create_student') def show_courses(self): # 查看所有课程 print('in Manager show_courses') def show_students(self): # 查看所有学生 print('in Manager show_students') 不用反射 alex = Manager('alex') operate_lst = ['创建课程','创建学生账号','查看所有课程','查看所有学生'] for index,opt in enumerate(operate_lst,1): print(index,opt) num = input('请输入您要做的操作 :') if num.isdigit(): num = int(num) if num == 1: alex.create_course() elif num == 2: alex.create_student() elif num == 3: alex.show_courses() elif num == 4: alex.show_students() 使用反射 alex = Manager('alex') operate_lst = [('创建课程','create_course'),('创建学生账号','create_student'), ('查看所有课程','show_courses'),('查看所有学生','show_students')] for index,opt in enumerate(operate_lst,1): print(index,opt[0]) num = input('请输入您要做的操作 :') if num.isdigit(): num = int(num) if hasattr(alex,operate_lst[num-1][1]): getattr(alex,operate_lst[num-1][1])()
shop 买东西类
1.浏览商品 scan_goods
2.选择商品 ,添加到购物车 choose_goods
3.删除商品 delete_goods
class Shop: def __init__(self,name): self.name = name def scan_goods(self): print('%s正在浏览商品'%self.name) def choose_goods(self): print('%s正在选择商品'%self.name) def delete_goods(self): print('%s正在删除商品'%self.name) s = Shop('self哥') s.choose_goods() s.scan_goods() s.delete_goods() if hasattr(s,'choose_goods'): # 判断s对象有没有choose_goods func = getattr(s,'choose_goods') # 使用s找到choose_goods对应的内存地址 print(func) func() content = input('') if hasattr(s,content): # 判断s对象有没有choose_goods func = getattr(s,content) # 使用s找到choose_goods对应的内存地址 print(func) func() opt_lst = ['scan_goods','choose_goods','delete_goods'] for index,opt in enumerate(opt_lst,1): print(index,opt) num = int(input('num :')) if hasattr(s,opt_lst[num-1]): getattr(s,opt_lst[num-1])() 和反射没关系 for i in Shop.__dict__.keys(): if not i.startswith('__'): print(i)
使用类反射
cls . 属性名
cls . 方法名()
class A: Country = '中国' @classmethod def show(cls): print('国家 : ',cls.Country) 'Country' print(getattr(A,'Country')) # print(A.Country) A.show # getattr(A,'show') 'show' getattr(A,'show')() # A.show()
使用模块反射
import time
time.time()
import re ret = re.findall('d+','2985urowhn0857023u9t4') print(ret) 'findall' getattr(re,'findall') # re.findall ret = getattr(re,'findall')('d','wuhfa0y80aujeiagu') print(ret) def func(a,b): return a+b wahaha = func ret = wahaha(1,2) print(ret)
import time time.time == getattr(time,'time') time.time() == getattr(time,'time')() 'time' now = getattr(time,'time')() print(now) time.sleep(1) print(321) getattr(time,'sleep')(1) # time.sleep(1) print(123)
反射本文件中的内容
只要是出现在全局变量中的名字,都可以用 getattr(modules[__name__] , 字符串数据类型的名字) 来获得
from sys import modules
语法 a = 1 b = 2 getattr(modules[__name__],'变量名') 函数名 def func(a,b): print('in func',a,b) getattr(modules[__name__],'func') # func func(1,2) getattr(modules[__name__],'func')(1,2) # func 类名 class Course: def func(self): print('in func') print(Course) 'Course' print(getattr(modules[__name__],'Course')) # Course getattr(modules[__name__],'Course')() # 实例化的过程
只要是a.b这种结构,都可以使用反射 用对象类模块反射,都只有以下场景 这种结构有两种场景 a.b b是属性或者变量值 getattr(a,'b') == a.b a.b() b是函数或者方法 a.b() getattr(a,'b')() a.b(arg1,arg2) getattr(a,'b')(arg1,arg2) a.b(*args,**kwargs) getattr(a,'b')(*args,**kwargs) 如果是本文件中的内容,不符合a.b这种结构
如果是这种方式,引用的模块就不是 from sys import modules , 而是直接引用 import sys 直接调用func() getattr(sys.modules[__name__],'func')() 直接使用类名 Person() getattr(sys.modules[__name__],'Person')() 直接使用变量名 print(a) getattr(sys.modules[__name__],'a') 所有的getattr都应该和hasattr一起使用 if hasattr(): getattr()
setattr
除了可以修改私有化的属性,还可以通过字符串数据类型的变量名,给一个对象创建一个新的属性
但 setattr 不可绑定方法
使用 setattr 创建了一个方法后,也只是创建在属性的内存空间中,而不是类的内存空间
这种方法不是正常的方法
所以 setattr 只用来绑属性
class A: def qqxing(self): print('qqxing') alex = A() alex.name = 'sb' print(alex.name) setattr(alex,'name','sb') # alex.name = 'sb' print(alex.name)
deleter
deleter(对象名,'属性')
删除对象的一个属性
和 setattr 一样,不能操作方法,只能操作属性
issubclass
判断类与类之间的关系
其实就是判断类与类之间是否有继承关系
issubclass(Son,Foo)
判断Son是不是Foo的子类
输出的结果是布尔值
object是任何类的父类,所以 insubclass(Son,object) 的结果总是 True
isinstance
判断对象与类之间的关系,这个 '类' 也包括父类
isinstance(obj,cls)
判断obj是否是cls或cls子类的对象
isinstance(obj,类) 判断时时承认继承关系的
类 = type(obj) 也可以判断类与对象的关系,但只承认实例化这个对象的那个类(不承认所有的继承关系)