Python反射机制

Python反射机制

1.前言

一个模块有变量、方法,如果我们在另一个模块中调用的时候会用到import。如果一开始不确定要导入的模块,如何通过手动输入模块名来实现功能呢?反射解决的就是这个问题,通过字符串的形式,导入模块;通过字符串的形式,去模块中寻找指定函数(或变量)并执行。

#test.py:
def f1():
    print("F1")
def f2():
    print("F2")

i = 5

使用import调用test中的方法和变量

import test as fun
fun.f1()
fun.f2()
print(fun.i)

使用__import__()方法可以实现接受动态输入模块名,随时动态的导入模块。(__import__可以导入字符串形式的模块)

inp = input("请输入要导入的模块名") #获取输入的模块名,得到为字符串
fun = __import__(inp)       #利用__import__函数获取字符串格式的模块
fun.f1()    #执行f1方法

当然,针对函数也可以进行动态调用,利用getattr(模块名,函数名)

inp = input("请输入要导入的模块名")
fun = __import__(inp)
inp_fun = input("请输入要执行的函数名")
f = getattr(fun,inp_fun)
f()

2.反射机制

除了上面介绍的导入模块,调用函数和变量外,还可以利用字符串形式操作模块、对象中的成员,包括查找、获取、删除、添加等。

1. getattr(object, name)

说明:导入模块并获取方法

2. hasattr(object, name)

说明:判断对象object是否包含名为name的特性(hasattr是通过调用getattr(ojbect, name)是否抛出异常来实现的)

3. setattr(object, name, value)

这是相对应的getattr()。参数是一个对象,一个字符串和一个任意值。字符串可能会列出一个现有的属性或一个新的属性。这个函数将值赋给属性的。该对象允许它提供。例如,setattr(x,“foobar”,123)相当于x.foobar = 123。

4. delattr(object, name)

与setattr()相关的一组函数。参数是由一个对象(记住python中一切皆是对象)和一个字符串组成的。string参数必须是对象属性名之一。该函数删除该obj的一个由string指定的属性。delattr(x, 'foobar')=del x.foobar

3.Web实例

考虑浏览器的页面跳转问题,根据用户输入的不同url,返回不同的页面内容,也就是一个url路由器功能,相同的思路是web框架的核心部件之一。

首先是一个commons模块
def login():
  print("这是一个登陆页面!")
 
def logout():
  print("这是一个退出页面!")
 
def home():
  print("这是网站主页面!")
其次是一个visit模块
import commons

def run():
  inp = input("请输入您想访问页面的url: ").strip()
  if inp == "login":
    commons.login()
  elif inp == "logout":
    commons.logout()
  elif inp == "home":
    commons.home()
  else:
    print("404")
 
if __name__ == '__main__':
  run()

这就实现了一个简单的web路由功能,根据不同的url,执行不同的函数,对应到浏览器就是返回不同的页面内容。这仅仅是三个函数功能,那么如果有几百个几千个不同的方法,是不可能全部if-else进行编写的,因此可以利用getattr()方法获取函数名,在继而判断是否存在此函数。

import commons
  
def run():
  inp = input("请输入您想访问页面的url: ").strip()
  if hasattr(commons,inp):
    func = getattr(commons,inp)
    func()
  else:
    print("404")
  
if __name__ == '__main__':
  run()

总结:反射即如何利用字符串执行不同的事件,比如导入模块,执行方法,查找变量,这些都是python的反射机制,是一种编程方法、设计模式,所以在java、c#中也有类似的功能实现,理解了运作模式和思路,实现都是比较好做的。

posted @ 2018-12-06 10:20 皂雨霏霏 阅读( ...) 评论( ...) 编辑 收藏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值