python--反射(python反射的作用和方法)

网友投稿 887 2022-08-25


python--反射(python反射的作用和方法)

什么是反射

反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!

python 里的反射有下面四种方法

hasattr(obj,name_str):判断一个对象 obj 里是否有对应的 name_str 字符串的方法getattr(obj,name_str):根据字符串去获取 obj 对象里的对应方法的内存地址setattr(obj,"y",z):相当于 obj.y=zdelattr(obj,name_str):删除属性

命名空间.XXX == getattr(命名空间,"XXX")

类名.名字

getattr(类名,"名字")

对象名.名字

getattr(对象,"名字")

模块名.名字

import 模块getattr(模块,”名字“)

自己文件.名字

import sysgetattr(sys.modules['__main__'],"名字")

类,静态属性,类方法,静态方法都可以反射

class Student: ROLE = 'STUDENT' @classmethod def check_course(cls): print('查看课程了') @staticmethod def login(): print('登录')print(Student.ROLE)print(getattr(Student, 'ROLE')) # 反射查看属性# 反射调用方法getattr(Student, 'check_course')() # 类方法getattr(Student, 'login')() # 静态方法

结果:

STUDENTSTUDENT查看课程了登录

hasattr和getattr

class Dog(object): def __init__(self, name): self.name = name def eat(self, food): print('%s is eating...' % self.name, food)d = Dog('张三')choice = input('请输入>>:').strip()# 不能d.choice() 会报错,因为choice是字符串print(hasattr(d, choice)) # 判断输入的在类里有没有这个方法,有返回True,否则Falseprint(getattr(d, choice)) # 返回了输入方法的内存对象getattr(d, choice)('鸡蛋') # 知道内存对象后加()传参调用

用户输入 eat 时,因为 Dog 类下有 eat 方法

请输入>>:eatTrue>张三 is

在输入 Dog 类下不存在的。比如 game

请输入>>:gameFalseTraceback (most recent call last): File "E:/git_test1/djago_DRF/DRFApi/apps/mtauth/tests.py", line 16, in print(getattr(d, choice)) # 返回了输入方法的内存对象AttributeError: 'Dog' object has no attribute 'game'

因为Dog下没有 game ,所以报错了

所以可以做个判断,如果  hasattr(d, choice) 返回为 True了,在执行  getattr(d, choice)

改写后的如下

class Dog(object): def __init__(self, name): self.name = name def eat(self, food): print('%s is eating...' % self.name, food)d = Dog('张三')choice = input('请输入>>:').strip()if hasattr(d, choice): # 判断输入的在类里有没有这个方法 func = getattr(d, choice) # 有这个方法执行,获得输入 的在类里方法的内存对象 func('鸡蛋') # 将参数传给func,相当于执行d.eat('鸡蛋')

在输入 eat

请输入>>:eat张三 is

输入 game

setattr

看如下例子

def bulk(self): # 装到类里必须要有self print('%s in the bulking...' % self.name)class Dog(object): def __init__(self, name): self.name = name def eat(self, food): print('%s is eating...' % self.name, food)d = Dog('张三')choice = input('请输入>>:').strip()if hasattr(d, choice): # 判断输入的在类里有没有这个方法 func = getattr(d, choice) # 有这个方法执行,获得输入的在类里方法的内存对象 func('鸡蛋') # 将参数传给func,相当于执行了d.eat('鸡蛋')else: # 输入的类里面的方法里没有 setattr(d, choice, bulk) # 等价于d.choice=bulk,动态加了个方法 d.talk(d) # 执行输入的,相当于执行了bulk,要把类对象传给,必须是d.输入的内容

输入 eat 时

请输入>>:eat张三 is

输入不存在的 game 时

当输入 talk 时

这时用户只能输入 eat 或者 talk ,输入其他会报错

如果想让输入 Dog类下不存在的方法,都执行 talk 下的,就可以这样写

def bulk(self): # 装到类里必须要有self print('%s in the bulking...' % self.name)class Dog(object): def __init__(self, name): self.name = name def eat(self, food): print('%s is eating...' % self.name, food)d = Dog('张三')choice = input('>>:').strip()if hasattr(d, choice): func = getattr(d, choice) # 有这个方法执行,获得输入的在类里方法的内存对象 func('鸡蛋') # 将参数传给func,相当于执行了d.eat('鸡蛋')else: # 输入的类里面的方法里没有 setattr(d, choice, bulk) # 等价于d.choice=bulk,动态加了个方法 func = getattr(d, choice) # 获得新加方法的内存对象 func(d) # 调用新加的方法,不管输入什么,都执行的是bulk里的

输入 eat

>>:eat张三 is

输入 game

>>:game张三 in

delattr

def bulk(self): # 装到类里必须要有self print('%s in the bulking...' % self.name)class Dog(object): def __init__(self, name): self.name = name def eat(self, food): print('%s is eating...' % self.name, food)d = Dog('张三')choice = input('请输入>>:').strip()if hasattr(d, choice): delattr(d, choice) # 删除属性,else: # 输入的类里面的方法里没有 setattr(d, choice, bulk) # 等价于d.choice=bulk,动态加了个方法 d.talk(d) # 执行输入的,相当于执行了bulk,要把类对象传给,必须是d.输入的内容print(d.name)

输入name

输入name,最后打印报错,因为属性name已经被删除了

反射应用的例子

import sysclass Manager: OPERATE_DIC = [ ('创造学生账号', 'create_student'), ('创建课程', 'create_course'), ('查看学生信息', 'check_student_info'), ] def __init__(self, name): self.name = name def create_student(self): print('创建学生账号') def create_course(self): print('创建课程') def check_student_info(self): print('查看学生信息')class Student: OPERATE_DIC = [ ('查看所有课程', 'check_course'), ('选择课程', 'choose_course'), ('查看已选择的课程', 'choosed_course') ] def __init__(self, name): self.name = name def check_course(self): print('check_course') def choose_course(self): print('choose_course') def choosed_course(self): print('查看已选择的课程')def login(): username = input('请输入user : ') password = input('请输入pwd : ') with open('user_info') as f: for line in f: user, pwd, ident = line.strip().split('|') # ident = 'Manager' if user == username and pwd == password: print('登录成功') return username, identdef main(): usr, id = login() print('user,id :', usr, id) file = sys.modules['__main__'] # 获取到该文件的内存对象 cls = getattr(file, id) # Manager = getattr(当前文件,'Manager') # cls ==< class '__main__.Manager'> obj = cls(usr) # 实例化类 operate_dic = cls.OPERATE_DIC # 调用类下的静态属性 while True: for num, i in enumerate(operate_dic, 1): print(num, i[0]) choice = int(input('num >>>')) choice_item = operate_dic[choice - 1] getattr(obj, choice_item[1])() # 执行类下的方法main()

当输入 zou 和123456 时

请输入user : zou请输入pwd : 123456登录成功user,id : zou Manager1 创造学生账号2 创建课程3 查看学生信息num >>>2创建课程1 创造学生账号2 创建课程3 查看学生信息num >>>3查看学生信息1 创造学生账号2 创建课程3 查看学生信息num >>>

当输入 test 666时

请输入user : test请输入pwd : 666登录成功user,id : test Student1 查看所有课程2 选择课程3 查看已选择的课程num >>>1check_course1 查看所有课程2 选择课程3 查看已选择的课程num >>>2choose_course1 查看所有课程2 选择课程3 查看已选择的课程num >>>3查看已选择的课程1 查看所有课程2 选择课程3 查看已选择的课程


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:python--反射(python反射的应用场景)
下一篇:SpringBoot框架中Mybatis
相关文章

 发表评论

暂时没有评论,来抢沙发吧~