python3中反射的应用
什么是反射?
在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性
它可以把字符串映射到实例的变量或者实例的方法然后可以去执行调用、修改等操作。
它有四个重要的方法:
- getattr 获取指定字符串名称的对象属性
- setattr 为对象设置一个对象
- hasattr 判断对象是否有对应的对象(字符串)
- delattr 删除指定属性
import random
class Student:
def __init__(self):
self._name = None
self._age = None
self._sex = None
def get_name(self):
return self._name
def set_name(self,name):
self._name = name
def get_age(self):
return self._age
def set_age(self,age):
self._age = age
def get_sex(self):
return self._sex
def set_sex(self,sex):
self._sex = sex
def get_student(self):
return self._name,self._age,self._sex
def set_student(self,name,age,sex):
self.set_name(name)
self.set_age(age)
self.set_sex(sex)
if __name__ == '__main__':
stu1 = Student()
stu1.set_name('zhangsan')
print(stu1.get_name())
stu1._age = 20
print(stu1._age)
module = __import__('reflex12_22.student',fromlist=['Student'])
# print(type(module))
# print(module)
# 利用类名字符串和模块的实例化对象来获取类,type类型的类
class_name = getattr(module,'Student')
# print(type(class_name))
# # print(class_name)
# 利用type类型的类直接构造类的实例化对象
stu2 = class_name()
# print(type(class_obj))
# print(class_obj)
# 利用构造的对象就可以进行类的任何合法操作
stu2.set_student('lisi',21,'male')
print(stu2.get_student())
# 利用hasattr检查指定的属性
if hasattr(stu2,'_name'):
# 利用hasattr读取指定的属性值
value = getattr(stu2,'_name')
print(value)
# 针对没有的属性,可以设置默认值
print(getattr(stu2,'_class',1))
if hasattr(stu2,'get_name'):
# 没有参数的方法
# 利用反射技术来执行类中的方法的处理其一
method = getattr(stu2,'get_name')
value = method()
print(value)
# 处理二
print(getattr(stu2,'get_age')())
# 有参数的方法调用
# 处理一
method = getattr(stu2,'set_sex')
method('female')
print(getattr(stu2,'get_sex')())
# 处理二
getattr(stu2,'set_name')('marry')
print(getattr(stu2,'get_name')())
if hasattr(stu2,'_name'):
print(hasattr(stu2,'_class'))
setattr(stu2,'_class','2')
print(getattr(stu2,'_class'))
stu3 = Student()
print(hasattr(stu3,'_class'))
delattr(stu2,'_class')
# print(getattr(stu2,'_class'))
print('***************反射的应用**********************')
# 利用__dir__或者dir方法来获取实例化对象的方法
methods = stu2.__dir__()
# print(methods)
methods = dir(stu2)
methods.sort(reverse=True)
# print(methods)
for method_name in methods:
# 利用方法名字符串和类的实例化对象来获取方法对象
if not method_name.startswith('_'):
method = getattr(stu2,method_name)
print(method_name)
if method_name.startswith('set'):
count = method.__code__.co_argcount - 1
args = []
for _ in range(count):
args.append(random.randint(100,1000))
# 通过方法对象类调用方法执行
method(*args)
print(method_name,args)
else:
print(method_name,method())