python 反射

反射 :

hasattr(obj, "attr")  : 判断对象是否具有某个属性或方法.

setattr(obj, "attr", value) : 给对象添加属性/方法, 及属性值,方法函数 --> 只存在于内存中, 不修改源码文件.

getattr(obj, "attr", default)  : 获取某个对象的属性或方法, 返回属性或方法. 如果属性不存在 , 则返回 default .
    对比 : obj.__dict__['attr']

    getattr(obj, "attr", None)     : 在 obj 中找不到 'attr' , 则返回 None.

delattr(obj, "attr")  : 从对象中删除属性或方法 --> 只存在于内存中.

示例代码 :

$ cat ./lib/test/com.py
    def foo():
        return "bar"

$ cat ./reflection.py

    def func(num):
        return num + 1

    n = __import__('lib.test.com', fromlist=True)       # 导入

    # hasattr() 
    if hasattr(n, 'foo'):           # 判断导入函数, 是否具有某sttr, 有则执行.
        print(n.foo())

    # setattr()
    setattr(n, 'func', func)        # 给对象添加新的属性/方法
    print(n.func(10))

    # delattr()
    delattr(n, 'func')              # 删除对象的属性方法,
    print(n.func(10))               # 此处, 将返回错误.

    # getattr()
    f = getattr(n, 'func')          # 获取对象的属性/方法.
    print(f(100))    


    # 基于类的示例 : 
    class MyClass:
        def __init__(self):
            self.name = 'tom'

        def get_ip(self):
            return 'ip'


    obj = MyClass()
    print(hasattr(obj, 'name'))     # True
    print(hasattr(obj, 'get_ip'))   # True

    setattr(obj, "age", 12)
    if hasattr(obj, "age"):
        print(getattr(obj, 'age'))      # 12
        delattr(obj, 'age')             # del attr
        print(hasattr(obj, 'age'))      # False

基于 反射 实现的 路由系统 :

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("Servering HTTP on port 8001 ...")
    httpd.serve_forever()

导入 :

import sys as obj       # 普通导入
obj.path

obj = __import__('sys') # 基于字符串的导入形式.
obj.path

导入嵌套路径 :

from lib.test import com    # 普通导入

com = __import__('lib.test.com', fromlist=True)     # 基于字符串的导入, 注意 fromlist 参数.
posted @ 2017-03-16 11:03  眼镜男  阅读(168)  评论(0编辑  收藏  举报