反射getattr、hasattr

反射:根据字符串的形式,去对象中(例如一个模块)去操作它的成员

通过字符串的形式,导入模块 __import__()

通过字符串的形式,去模块中寻找指定函数或变量,并执行  getattr(model,fuc)

import re as aa 

bb = __import__("re")

aa == bb

  

注意:如果导入的文件包含在下级文件夹中,需要加一个参数:

bb=__import__("lib.test.com",fromlist = True)

 

getattr(model,func) #执行model模块下的func函数

f = getattr(re,"findall")

f() #执行re.findall()

  

 例子:

一个模块test.py,包含一个函数f1()

test.py

def f1():

  print("this is f1")

  

新建一个py:

inp = input("请输入模块名:")

dd = __import__(inp)

inp_fuc = input("输入函数名:")

r = getattr(dd,inp_fuc)

r()

  

注意:

r = getattr(dd,inp_fuc),如果输入的字符串对应的函数不存在,则会报错,所以可以设置一个默认值:

r = getattr(dd,inp_fuc,None),这样如果函数不存在,则返回None

另外:getattr(模块名,“函数或变量”),模块名后面,不仅仅可以是函数对应的字符串,也可以是模块中的变量对应的字符串

  

hasattr() #根据字符串的形式判断模块中东西是否存在

hasattr(module,"var") #判断module中是否有var,返回True或False

 

setattr()  #可以给模块设置一个函数或者全局变量,只是在内存中操作,不影响原来模块文件内容

setattr(module,"SAA",18) #给模块moudule设置了一个全局变量SAA=18,也可以是函数:SAA后面跟一个lambda表达式

 

delattr() #删除模块中的某个函数或者变量

delattr(module,"SAA") #删除module中的SAA变量,都是在内存中操作,不影响原来的模块文件

 

基于反射实现类似WEB框架的路由系统:

例1:用户输入一个字符串,通过反射找到指定模块中的函数并执行

from lib import account

url = input("input url:")

inp = url.split("/")[-1]

if hasattr(account,inp):  #判断account中是否有inp所反射的函数

  target_func = getattr(account,inp)  #找到函数(未执行)

  r = target_func()  #执行函数,拿到返回值

  print(r)

else:

  print("404") 

 

 

例2:用户输入一个字符串(模块\函数),通过反射导入相关模块,并执行其中的函数

url = input("input url:")

target_module, target_func = rul.split("\") 

m = __import__("lib." + target_module, fromlist = True)

if hasattr(m, target_func):

  target_func = getattr(m, target_func)

  r = target_func()

  print(r)

else:

  print("404") 

  

 

 

posted @ 2018-08-30 15:38  greenfan  阅读(203)  评论(0)    收藏  举报