python反射

Posted FuZZ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python反射相关的知识,希望对你有一定的参考价值。

python反射

python的反射是基于字符串的形式去对象(模块)中操作其成员。此操作是动态的,常用于web开发中url参数中对应模块或者函数的反射。
下面开始具体说明:

  • 场景需求:

我的python脚本中有一百个函数,当前端页面被访问到之后,针对特定的url 我后端有特定的函数进行处理,我该如何判断这个URL需要后端那个函数来处理呢?写if判断?别闹了。一百多个呢,那执行效率会有多慢。看下面代码:

def f1():
    print("f1")

def f2():
    print("f2")


def f3():
    print("f3")

res = input("请输入url: ")
if res == f1:
    f1()
elif res == f2:
    f2()
elif res == f3:
    f3()
else:
    print("404")
    
执行结果:
请输入url: f1
f1

请输入url: f2
f2

请输入url: f3
f3

请输入url: adasd
404

 

现在是定义了3个函数,如果100个的,我得写100个if判断,那不疯了。。。
下面耍个小聪明,使用dict映射来做

def f1():
    print("f1")

def f2():
    print("f2")


def f3():
    print("f3")

func_map = {
    f1:f1,
    f2:f2,
    f3:f3,
}
res = input("请输入url: ")

if res in func_map:
    func_map[res]()
else:
    print(404)
    
 输出结果:
 
 
请输入url: f1
f1

请输入url: f2
f2

请输入url: f3
f3

请输入url: asdad
404

 

发现还是很麻烦。字典需要写很长影射,而且后期我加一个函数,还得在字典中手动添加对应的影射关系,万一写错了。就悲催了。。。。下面反射就出来了,就可以很好解决此问题!

  • 反射getattr处理
class getfunc():
    def f1(self):
        print("f1")

    def f2(self):
        print("f2")


    def f3(self):
        print("f3")

res = input("请输入url: ")

obj_func = getfunc()
func = getattr(obj_func,res)
func()

输出结果:


请输入url: f1
f1

请输入url: f2
f2

请输入url: f3
f3

请输入url: f4
Traceback (most recent call last):
  File "反射.py", line 55, in <module>
    func = getattr(obj_func,res)
AttributeError: getfunc object has no attribute f4

 

这里我们使用的是类的作法,先创建一个类,将所有函数放在类里。在调用前先实例化该类,不论类里有多少个函数,直接根据输入内容通过getattr调用类里的函数。这样后期不管添加多少函数,只要前端能调用符合要求,则都会被调到。
发现最后一个怎么报错?原来并没有匹配到f4这个函数。反射也提供了检查功能,类似于检查一个字典是否存在某个key一样。下面说明一下反射的基本操作类型

  • 反射的操作类型:
    • getattr() 查找
    • setattr() 设置
    • hasattr() 判断
    • delattr() 删除 接着上面的类说明操作类型的用法:
class getfunc:
    def __init__(self):
        self.test = 1234
    def f1(self):
        print("f1")

    def f2(self):
        print("f2")


    def f3(self):
        print("f3")

foo = getfunc()
print(hasattr(foo,f1))    判断是否有f1
print(hasattr(foo,f5))        判断是否有f5

print(setattr(foo,f5,f1))   设置f5为f1
print(getattr(foo,f5))    判断是否有f5

print(delattr(foo,test))  删除test
print(hasattr(foo,test))   判断是否有test

运行结果:
True
False
None
f1
None
False

 

同样模块也支持动态导入,看下面说明:

  • 反射模块

模块动态导入使用__import__方法

定义一个模块:fanshe
def login():
    print(登录页面)


def logout():
    print(退出页面)


def home():
    print("主页面")

下面是调用代码:
inp = input("请输入url:")
m,f = inp.split(/)
try:
   obj = __import__(m)
except:
   print("404")
   sys.exit()
if hasattr(obj,f):
   func = getattr(obj,f)
   func()
else:
   print("404")

执行结果:

请输入url:fanshe/login
登录页面

请输入url:fanshe/logout
退出页面

请输入url:fanshe/home
主页面

 

反射太强大了。

以上是关于python反射的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL片段着色器不照亮场景

将 OpenGL 片段着色器设置为仅通过漫反射减少 vec4 色点的 RGB 值,而不是 alpha

反射机制

反射机制入门

反射机制入门

反射机制入门