反射: 以字符串类型的变量名或方法名去操作变量或方法 -> hasattr() getattr() setattr() delattr()
hasattr(对象, '变量名/方法名') -> 判断对象是否有该变量/方法
class Reflection:
def __init__(self):
self.age = 22
r = Reflection()
print(hasattr(r, 'age')) # True
getattr(对象, '变量名/方法名') -> 以字符串类型的变量名或方法名去操作变量或方法
- hasattr() 一般配合着 getattr() 使用
class Reflection:
def __init__(self):
self.age = 22
r = Reflection()
if hasattr(r, 'age'): # 判断对象是否有该属性
a = getattr(r, 'age') # 以字符串类型的属性名去获取对象中的属性值
print(a) # 22
setattr(对象, '变量名', 值) -> 设置或修改变量 -> 没啥用
class SetEdit(): pass
s = SetEdit()
setattr(s, 'name', 'Kevin') # 设置或需改变量名
print(s.name) # Kevin
delattr(对象, '变量名') -> 删除一个变量 -> 没啥用
class SetEdit():
def __init__(self):
self.name = 'Kevin'
s = SetEdit()
delattr(s, 'name') # 删除一个变量
print(s.name) # 报错
1. 反射对象的属性和方法
- 反射对象属性
class Reflection:
def __init__(self):
self.age = 22
r = Reflection()
if hasattr(r, 'age'): # 判断对象是否有该属性
a = getattr(r, 'age') # 以字符串类型的属性名去获取对象中的属性值
print(a)
- 反射对象方法
class Reflection:
def r_fn(self):
print('对象中的方法')
r = Reflection()
if hasattr(r, 'r_fn'): # 判断对象是否有该方法
rFn = getattr(r, 'r_fn') # 返回值:绑定方法 -> 以字符串类型的方法名去获取对象中的方法
print(rFn) # <bound method Reflection.r_fn of <__main__.Reflection object at 0x00000264ABEF1F98>>
rFn() # 调用绑定方法
2. 反射类的静态属性/类方法/静态方法
- 反射类的静态属性
class Reflection:
static_attr = '静态属性'
if hasattr(Reflection, 'static_attr'): # 判断类中是否有该静态属性
s_a = getattr(Reflection, 'static_attr') # 以字符串类型的静态属性名去获取类中的静态属性值
print(s_a) # 静态属性
- 反射类的类方法
class Reflection:
@classmethod
def rc_fn(cls):
print('类方法')
if hasattr(Reflection, 'rc_fn'): # 判断类中是否有该类方法
rcFn = getattr(Reflection, 'rc_fn') # 返回值:绑定方法 -> 以字符串类型的类方法名去获取类中的类方法
print(rcFn) # <bound method Reflection.rc_fn of <class '__main__.Reflection'>>
rcFn() # 调用绑定方法
- 反射类的静态方法
class Reflection:
@staticmethod
def s_fn():
print('静态方法')
if hasattr(Reflection, 's_fn'): # 判断类中是否有该静态方法
s_fn = getattr(Reflection, 's_fn') # 以字符串类型的静态方法名去获取类中的静态方法
print(s_fn) # <function Reflection.s_fn at 0x0000029324FB6C80>
s_fn() # 调用方法
3. 在类中反射类自身的属性和方法
- 在类中反射类自身的属性
class Reflection:
def __init__(self):
self.age = 18
def ref_fn(self):
if hasattr(self, 'age'): # 判断self中是否有该属性
age = getattr(self, 'age') # 以字符串类型的属性名去获取self中的属性值
print(age) # 18
r = Reflection()
r.ref_fn()
- 在类中反射类自身的静态属性
class Reflection:
static_attr = '静态属性'
def ref_fn(self):
if hasattr(self, 'static_attr'): # 判断self中是否有该静态属性
static_attr = getattr(self, 'static_attr') # 以字符串类型的静态属性名去获取self中的静态属性值
print(static_attr) # '静态属性'
r = Reflection()
r.ref_fn()
- 在类中反射类自身的方法
class Reflection:
def fn(self):
print('类的方法')
def ref_fn(self):
if hasattr(self, 'fn'): # 判断self中是否有该方法
fn = getattr(self, 'fn') # 以字符串类型的方法名去获取self中的方法
print(fn) # <bound method Reflection.fn of <__main__.Reflection object at 0x000001DC9616E908>>
fn() # 类的方法
r = Reflection()
r.ref_fn()
4. 反射模块的变量和方法
# my.py
my_data = '数据'
def my_fn():
print('模块中的方法')
import my
# 反射模块中的变量
if hasattr(my, 'my_data'):
m_d = getattr(my, 'my_data')
print(m_d)
# 反射模块中的方法
if hasattr(my, 'my_fn'):
my_fn = getattr(my, 'my_fn')
my_fn()
5. 反射内置模块
import time
if hasattr(time, 'time'):
t_s = getattr(time, 'time')() # 直接调用通过 getattr 获取到的方法
print(t_s) # 1550023996.0530589
6. 反射自身模块(自身脚本文件)的变量和函数
import sys
year = 2019
def y_fn(s):
print(s)
# 通过 sys.modules 获取当前模块
# self_module = sys.modules['__main__']
self_module = sys.modules[__name__] # 最好不要使用 '__main__' 去获取当前模块,虽然 __main__ 代表当前模块名,因为如果当前模块是要被引用的那么此时的 __main__ 指向的是引用该模块的文件,通过 __name__ 可以动态的获取当前的模块名
# 获取当前模块的变量
print(getattr(self_module, 'year'))
print(getattr(sys.modules[__name__], 'year')) # 推荐使用
# 获取当前模块的方法并且调用
getattr(self_module, 'y_fn')('今年是2019年')
getattr(sys.modules[__name__], 'y_fn')('今年是2019年') # 推荐使用
7. 通过反射获取到的方法的执行方式
- 将方法赋值后再调用
class Reflection:
def r_fn(self, s):
print(s)
r = Reflection()
if hasattr(r, 'r_fn'):
rFn = getattr(r, 'r_fn')
rFn('调用通过反射得到的方法')
- 直接调用方法 -> 因为 getattr(对象, '方法名') 返回的就是一个函数或方法,所以可以直接在后面加()执行
class Reflection:
def r_fn(self, s):
print(s)
r = Reflection()
if hasattr(r, 'r_fn'):
getattr(r, 'r_fn')('调用通过反射得到的方法')
8. 使用反射的例子
class Teacher:
dic = {'查看学生信息': 'show_student', '查看讲师信息': 'show_teacher'}
def __init__(self):
self.name = 'Kevin'
def show_student(self):
print('查看学生信息')
def show_teacher(self):
print('查看讲师信息')
t = Teacher()
print(hasattr(t, 'name')) # True
for k in Teacher.dic:
print(k)
key = input('请输入需求:')
if hasattr(t, Teacher.dic[key]): # 先检测对象中是否有该对象
print(getattr(t, 'name'))
func = getattr(t, Teacher.dic[key]) # 以字符串的形式调用变量/属性/函数/方法
func()