python 高级编程之反射

1.反射

  在java中经常听到反射,JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性(摘自百度百科)。对比java中反射的定义,在python中就是称为自省的东西。

 

2.应用场景

  在web应用中一个核心的功能就是路由,通过不同的url调用不同的函数来实现不同的操作,当然你可这样实现

def func1():
    print 'func1'

def func2():
    print 'func2'

url = input().strip()
if url == 'func1':
    func1()
elif url == 'func2':
    func2()

在python中就可以用自省(反射)来解决这一类问题。当url为func1使,输出func1,这并没有什么问题,但是这里有一个缺陷,如果你的网站非常大,url非常多,这样写就非常的不方便。

 

3.python自省

  自省就是在运行过程让对象自己告诉我们它有什么,自省的四大核心属性:

  • dir([obj]): 调用这个方法将返回包含obj大多数属性名的列表(会有一些特殊的属性不包含在内)。obj的默认值是当前的模块对象。
  • hasattr(obj, attr): 这个方法用于检查obj是否有一个名为attr的值的属性,返回一个布尔值。
  • getattr(obj, attr): 调用这个方法将返回obj中名为attr值的属性的值,例如如果attr为'bar',则返回obj.bar。
  • setattr(obj, attr, val): 调用这个方法将给obj的名为attr的值的属性赋值为val。例如如果attr为'bar',则相当于obj.bar = val。

上述的例子可以做如下修改:

class Handle(object):
    def func1(self):
        print 'func1'

    def func2(self):
        print 'func2'

handle = Handle()
url = input().strip()
if hasattr(handle, url):
    func = getattr(handle, url)
    func()

我有见过将所有的func保存在一个字典里,不同的字符串对应不同的执行函数,例如如上述代码所示,完全不需要将所有的东西都写死,这个完全是动态获取执行的。

{'func1': func1, 'func2': func2}

还是那个问题,如果你这张路由表很小,当然没有什么问题,但是一旦处理函数非常多的话,单单维护这张表就很困难了。

python的自省工能就可以非常容易的通过字符串来获取对应的执行函数,简单粗暴。

 

4.进一步

  在web开发中通常会面临这样一个问题,如果我们的web项目非常庞大,夸张一点,各种处理模块成千上万,如果所有的模块都需要导入的话是否太麻烦了,而且后期维护也异常不便。

在python中有一个叫动态加载机制,python提供了一个特殊的方法:__import__(字符串参数)。通过它,我们就可以实现类似的反射功能。__import__()方法会根据参数,动态的导入同名的模块。

上述代码又可以做如下修改:

# module handle.py
class Handle(object):
    def func1(self):
        print 'func1'

    def func2(self):
        print 'func2'

# module run.py
module, func = input().strip().split('/')
handle = __import__(module)
handle = handle.Handle()
if hasattr(handle, url):
    func = getattr(handle, url)
    func()

非常方便,当然在实际的应用中需要严格设计你的web api,风格类似于这种module/func。__import__没有类似于hasattr的功能,所以需要处理好异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值