Python中的反射问题
1.先简单的介绍一下什么是Python中的反射
到目前我了解的内容来看,Python中的反射问题主要是三个函数的使用,hasattr() getattr() delattr(),先说前两个,后续会持续更新这篇文章
先看一段代码简单了解一下:
class Teacher:
dic = {'student':'show_student','teacher':'show_teacher'}
def show_student(self):
print('show_student')
def show_teacher(self):
print('show_teacher')
@classmethod
def func(cls):
print('hahahhah')
# 现在我想拿到字典有两种方式
print(Teacher.dic)
dic = getattr(Teacher,'dic')
print(dic)
# 上面可以得到相同的结果 但是有什么样的作用呢体现的不是太明显
# 下面再看拿到类里面的函数
func = getattr(Teacher,'func')# 这里拿到的是函数的地址,想执行函数还得加()
func() #执行上面的函数
# 从上面的例子可以看出hasattr() getattr() delattr()
# 的使用规则很简单,只要原本是 类/对象.属性/方法
# 就可以写成 getattr(类/对象,'属性/方法') 使用很简单
#往往hasattr和getattr是成对出现的搭配着使用,有时我们会出现这样的需求就是
#根据输入的内容或者选项执行相应的函数,下面展示一下简单的使用场景
# 在后面的网络编程反射的作用很大
# 现在我想根据用户的输入选着展现相应的内容:
alex = Teacher()
if hasattr(Teacher,'dic'):
menu = getattr(Teacher,'dic')
key = input('>>>')
if hasattr(alex,menu[key]): #判断字典内是否有相应的内容 有就是True
func = getattr(alex,menu[key])#拿到键值对的值并返回跟值一样的函数的地址
func()# 执行函数
下面是后期的总结主要有以下几个方面的使用
1.反射类里面的方法,变量
import sys
class A:
sex = '男'
@classmethod
def func(self):
print('类里面的方法')
a = A()
a.name = 'alex'
a.sex = '女'
print(a.name)
# 1.调用类和对象里面的变量
print(getattr(a,'name'))
print(getattr(A,'sex'))
print(getattr(a,'sex'))
# 在打印对象和类的属性的时候有一个原则就是,当对象没有这个属性的
# 时候会向上搜寻,找类里面是否有这个变量,有就打印
2.调用类里面的方法
ret = getattr(A,'func')
ret()
# 注意在使用反射的手法的时候一定要注意使用@classmethod对方法进行装饰
# 这里面的代码和上面 “1.反射类里面的方法,变量”是一起的要运行同时复制下面代码也是一样从这之后都是在一个py文件中的
# 调用方法的一个使用场景
name = input('>>')
ret = getattr(A,name)
ret()
3.调用模块里面的方法和属性
import my
print(getattr(my,'name'))
ret = getattr(my,'function')
ret()
#my.py文件的类容
name = '二狗偶'
def function():
print('模块里面的function函数')
4.调用本文件的方法和属性
name = '本文件'
def sel():
print('本文件的sel方法')
print(getattr(sys.modules['__main__'],'name'))
ret = getattr(sys.modules[__name__],'sel')
ret()
# 注意这里使用的sys.modules[__name__] 中的__name__是很有讲究的
# 如果在本文件中完全可以将sys.modules[__name__] 换成sys.modules['__main__']
# 但是如果该文件被别的文件import了这里的__main__就发生变化了,调用的东西就会出错
# 所以要换成__name__给他变成一个变量,这样就可以避免错误