反射

反射

  有时候我们会碰到这样的需求,需要执行对象的某个方法,或是需要对对象的某个字段赋值,而方法名或是字段名在编码代码时并不能确定,需要通过参数传递字符串的形式输入。举个具体的例子:当我们需要实现一个通用的DBM框架时,可能需要对数据对象的字段赋值,但我们无法预知用到这个框架的数据对象都有些什么字段,换言之,我们在写框架的时候需要通过某种机制访问未知的属性,这个机制被称为反射

python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

# hasattr(obj,str_name) 判断一个对象里是否有对应的str_name字符串属性
#getattr(obj,str_name) 根据字符串str_name去获取obj对象的对应属性的内存地址
# setattr(obj,'y',v ) Sets the named attribute on the given object to the specified value.将给定对象上的命名属性设置为指定的值 setattr(x, 'y', v) is equivalent to ``x.y = v''
#delattr(obj,str_name) 删除obj对象的str_name字符串属性
def Talk(self):
    print("%s is talking..."%self.name)

class Dog(object):
    def __init__(self,name):
        self.name=name
    def eat(self,food):
        print("%s is eating %s"%(self.name,food))
        
d=Dog('小黑')
choice=input(">>:").strip()
if hasattr(d,choice):
    # func=getattr(d,choice)
    # func('something')
    delattr(d,choice)

else:
    # setattr(d,choice,Talk) 添加动态属性
    # func=getattr(d,choice)
    # func(d)
    setattr(d,choice,None) #添加静态属性
    print(getattr(d,choice))
    print(d.choice)
示例
from wsgiref.simple_server import make_server

class Handler(object):

    def index(self):
        return 'index'

    def news(self):
        return 'news'


def RunServer(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    url = environ['PATH_INFO']
    temp = url.split('/')[1]
    obj = Handler()
    is_exist = hasattr(obj, temp)
    if is_exist:
        func = getattr(obj, temp)
        ret = func()
        return ret
    else:
        return '404 not found'

if __name__ == '__main__':
    httpd = make_server('', 8001, RunServer)
    print "Serving HTTP on port 8000..."
    httpd.serve_forever()
web框架实例

结论:反射是通过字符串的形式操作对象相关的成员。一切事物都是对象!!!

import sys

def s1():
    print 's1'

def s2():
    print 's2'

this_module = sys.modules[__name__]

hasattr(this_module, 's1')
getattr(this_module, 's2')
反射当前模块

类也是对象

class Foo(object):
    staticField = "school"

    def __init__(self):
        self.name = 'Mike'

    def func(self):
        return 'func'
    
    @staticmethod
    def bar():
        return 'bar'

print(getattr(Foo, 'staticField'))
print(getattr(Foo, 'func'))
print(getattr(Foo, 'bar'))

#执行结果
school
<function Foo.func at 0x01A135D0>
<function Foo.bar at 0x01A13618>
View Code

模块也是对象

def dev():
    return 'dev'
home.py
"""
程序目录:
    home.py
    index.py
 
当前文件:
    index.py
"""
 
import home as obj
 
#obj.dev()
 
func = getattr(obj, 'dev')
func() 

 

posted @ 2017-02-22 20:35  似是故人来~  阅读(170)  评论(0编辑  收藏  举报