引入
1.什么 反射
- 反射就是通过字符串来操作类或者对象的属性
- Python中一切皆对象, 即都可以使用反射
2.反射的四个内置函数
反射的本质就是在使用内置函数, 其中反射有以下四个内置函数
-
hasattr : 判断一个属性或方法是否存在这个类中, 返回bool值
-
getattr : 获取属性值或者获取方法变量的内存地址 (根据字符串去获取obj对象里的对应的方法的内存地址 (加括号"()"就可以调用))
-
setattr : 给类或对象设置属性或方法 (通过setattr将外部的一个属性或函数绑定到实例中)
-
delattr : 删除类或对象的属性和方法
ps : getattr, hasattr, setattr, delattr对模块的修改都在内存中进行,并不会影响文件中真实内容
一.反射模块
1.模块导入到模块动态导入
- 之前我们使用模块都是使用 import 的方式进行导入
🍔文件 test24.py
def Foo1():
print("i am test24_Foo1")
def Foo2():
print("i am test24_Foo2")
def Foo3():
print("i am test24_Foo3")
🍔文件 test反射.py
import test24
test24.Foo1() # i am test24_Foo1
test24.Foo2() # i am test24_Foo2
test24.Foo3() # i am test24_Foo3
- 通过反射模块的方式动态的导入模块, Python提供了
__import__
来实现这一功能
🍔文件 test反射.py
Inp = input("请输入想要导入的模块>>").strip()
mode = __import__(Inp) # 通过字符串的方式导入你想要的导的模块
mode.Foo1()
mode.Foo2()
mode.Foo3()
'''输出
请输入想要导入的模块>>test24
i am test24_Foo1
i am test24_Foo2
i am test24_Foo3
'''
- 问题 : 当我们的模块文件路径与执行文件不在同一级, 如下图所示
🍔文件 setting.py
def Foo1():
print("i am setting_Foo1")
🍔文件 test反射.py
Inp = input("请输入想要导入的模块>>").strip()
mode = __import__(Inp)
mode.Foo1()
'''输出
请输入想要导入的模块>>conf.setting
抛出异常 "AttributeError: module 'conf' has no attribute 'Foo1'"
'''
- 解决方法
Inp = input("请输入想要导入的模块>>").strip()
mode = __import__(Inp,fromlist=True) # 添加参数
mode.Foo1()
'''输出
请输入想要导入的模块>>conf.setting
i am setting_Foo1
'''
2.第二种反射模块方法
- 使用
importlib
模块实现 (在Python3 框架中使用的比较多)
🍔文件 test26.py
def test():
print("i am test26")
🍔文件 test反射模块.py
import importlib
In