概念:
python中的反射就是通过字符串的形式去模块,对象中找寻指定的函数(方法)并执行
常用途:
使用字符串的形式去模块中对模块中的成员进行增删改查。
如果我有test.py这个模块;并且在其中定义三个函数,和一个全局变量count_number:
def f1(): print('我是f1函数') def f2(): print('我是f2函数') def f3(): print('我是f3函数') count_number = 100
那么在另外一个同级的文件里我可以像平时一样导入:
import test as cc cc.f1() cc.f2() cc.f3() print(cc.count_number)
执行结果肯定木有问题:
我是f1函数
我是f2函数
我是f3函数
100
问题1: 但是此时的需求变了,我们需要让用户自己输入模块名称,该怎么办呢?
如果像要以字符串的方式进行导入,需要使用__import__():
imp = input('请输入要导入的模块名称') imp_module = __import__(imp) imp_module.f1() imp_module.f2() imp_module.f3() print(imp_module.count_number)
执行并输入test:
请输入要导入的模块名称test
我是f1函数
我是f2函数
我是f3函数
100
问题2: 如果我想要自己手动输入需要执行的函数呢?
那么我们就需要介绍反射中常用的四个函数了:
1----getattr()
作用:找到指定对象中的指定成员,如果存在则返回成员引用,否则返回None
答问题2:我们可以利用getattr()
imp = input('请输入要导入的模块名称') imp_module = __import__(imp) func_name = input('输入要导入的函数名称') # getattr()的作用是从我们导入的模块中,找到指定名称的函数,并返回该函数的引用 # 参数1,函数成员所在的模块, # 参数2,要的函数名称 # 参数3,没有找到返回None func = getattr(imp_module, func_name, None) if func != None: func() else: print('没有找到您输入的函数')
执行,并输入test,f2测试:
请输入要导入的模块名称test 输入要导入的函数名称f2 我是f2函数
这个例子我们就实现了动态导入一个模块,并且动态的输入模块成员进行调用。
2----hasattr():
作用:判断指定对象中是否含有指定成员,有则返回True,否则返回False。
3----setattr():
作用:给指定对象添加指定成员
4----delattr():
作用:删除指定对象中的指定成员
我们看下面的类使用以上四个函数:
class Person(object): def __init__(self, name, age): self.name = name self.age = age def say_hello(self): print('hello I am%s' % self.name) person = Person('张飞龙', 19) # 给对象动态添加的属性也可以通过getattr()获得 person.gender = '男' func = getattr(person, 'say_hello', None) func()
结果:
hello I am张飞龙
在继续添加代码:
name = getattr(person, 'name', None) age = getattr(person, 'age', None) gender = getattr(person, 'gender', None) print(name) print(age) print(gender)
执行:
hello I am张飞龙
张飞龙
19
男
添加:
print(hasattr(person, 'say_hello'))
执行:
True
setattr(person, "height", 187) setattr(person, 'sayhello2', lambda:print('say hello 2222')) print(person.height) person.sayhello2()
打印:
187 say hello 2222
添加代码:
delattr(person, 'height') if not hasattr(person, 'height'): print('person的height已经删除了')
执行:
person的height已经删除了反射,就是这个样子的!!