标签:读取 service python 简化 ready param asa 取出 read
开局篇我们说了。RPC框架的四个核心内容
def procRequest(self):
# 循环读取并处理收到的client请求
while True:
req = self.conn.recv()
rsp = Response()
rsp.id = req.id
if req.command == 'sayHello':
rsp.result = self.sayHello()
elif req.command == 'whoAreYou':
rsp.result = self.whoAreYou()
else:
raise Exception("unknown command")
self.conn.send(rsp)有什么办法能够避免吗?有,就是引入服务注冊机制。在这里。实际就是将command与详细的function object绑定起来,说穿了就是生成一个dict,
{‘sayHello’ : self.sayHello, ‘whoAreYou‘: self.whoAreYou}。
有这种dict之后,收到req 之后,仅仅要提取出command字段。然后从dict中找出相应的function。调用该function就可以。
基本想法已定,
这个实现非常easy。self.services就是上面的dict。通过register()去注冊服务。通过get_service()去获取服务名相应的function
class ServiceRegister(object):
'''
@服务注冊 不考虑线程安全,这里简化起见,也不引入反射机制。
'''
def __init__(self):
'''
Constructor
'''
self.services = {}
## 注冊详细的服务
# @param servicename: 服务名
# @param obj: 详细的对象
def register(self, obj, servicename):
if servicename in self.services:
print('warning: %s is already registered' % servicename)
else:
self.services[servicename] = obj
def get_service(self, servicename):
return self.services[servicename]
def list_service(self, servicename=None):
if servicename:
return str({servicename, self.services[servicename]})
else:
return str(self.services)服务注冊:
self.services.register(self.sayHello, 'Server.sayHello', )
self.services.register(self.whoAreYou, 'Server.whoAreYou')
self.services.register(self.add, 'Server.add')服务查找def proc(self, req):
rsp = Response()
rsp.id = req.id
rsp.result = ServiceCaller.call(self.services.get_service(req.command), req.parameter)
......class ServiceCaller():
def __init__(self):
pass
@classmethod
def call(cls, caller, parameter):
if not parameter or len(parameter) == 0:
return caller()
return caller(**parameter)class AutoServiceRegister(AbstractServiceRegister):
def register_class(self, obj, predicate=None):
if not (hasattr(obj, '__class__') and inspect.isclass(obj.__class__)):
return False
servicename = obj.__class__.__name__
for (name, attr) in inspect.getmembers(obj, predicate):
# 系统方法或者私有方法,不加入
if name.startswith('__') or name.startswith('_' + servicename + '__'): continue
#print(name)
if inspect.ismethod(attr): self.register_method(attr)
elif inspect.isfunction(attr): self.register_function(attr, servicename)
return Trueif __name__ == '__main__':
class AServer(object):
def __init__(self):
pass
def sayHello(self):
return 'Hello World'
def whoAreYou(self):
return 'I am server'
def __kaos(self):
pass
def _kaos(self):
pass
obj = AServer()
service = AutoServiceRegister()
print(service.register_class(obj))
print(service.list_services())
print(service.get_service('AServer.sayHello')) True
{'AServer': {'sayHello': <bound method AServer.sayHello of <__main__.AServer object at 0x000000000294EA90>>, 'whoAreYou': <bound method AServer.whoAreYou of <__main__.AServer object at 0x000000000294EA90>>, '_kaos': <bound method AServer._kaos of <__main__.AServer object at 0x000000000294EA90>>}}
<bound method AServer.sayHello of <__main__.AServer object at 0x000000000294EA90>>有兴趣的同学能够先去了解一下inspect
同一时候像__init__, __kaos, _kaos之类的系统固有方法,或者私有方法。会自己主动剔除。
尽管在python中,也支持类对象,但假设直接传递类对象,就会遇到怎样初始化的难题。所以这里一致要求,必须是类的实例。
if not (hasattr(obj, '__class__') and inspect.isclass(obj.__class__)):
return False类实例的特点就是,包括__class__成员,并且__class__成员的值就是该类的类对象。inspect.isclass就是检測是不是类对象
假设是,就注冊进来
总结:
1. 引入服务注冊的方式也是为了代码解耦,将req的处理与详细的req消息内容解耦。
2. 上面我们 引入了两种服务注冊的方式。一种方式是普通的方式,逐个加入方法。
还有一种方式通过python的“反射”技术,自己主动查找一个类里面的方法。并自己主动加入。
3. 方案还是非常粗糙的,实际有非常多优化的地方。
标签:读取 service python 简化 ready param asa 取出 read
原文地址:http://www.cnblogs.com/blfbuaa/p/7294150.html