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 参数.