Python描述符与元类结合:声明式API框架设计
结合描述符和元类设计一个声明式API框架。要求:1)使用描述符定义API端点(如GET('/users'));2)使用元类自动收集端点注册到路由表;3)支持参数验证和文档生成。说明为什么描述符+元类的组合适合声明式编程范式,并给出一个简化的Web框架控制器示例。
回答
我还是少年
import inspect
class Route:
def __init__(self, path, methods=['GET']):
self.path = path
self.methods = methods
self.handler = None
def __set_name__(self, owner, name):
self.name = name
def __get__(self, obj, objtype=None):
if obj is None:
return self
return self.handler.__get__(obj, objtype)
def __set__(self, obj, value):
self.handler = value
class ControllerMeta(type):
def __new__(mcs, name, bases, namespace):
routes = {}
for attr_name, attr_val in namespace.items():
if isinstance(attr_val, Route):
routes[attr_val.path] = {
'handler': attr_name,
'methods': attr_val.methods
}
namespace['_routes'] = routes
return super().__new__(mcs, name, bases, namespace)
class Controller(metaclass=ControllerMeta):
@classmethod
def register(cls, app):
for path, info in cls._routes.items():
handler = getattr(cls, info['handler'])
app.add_route(path, handler, methods=info['methods'])
# 使用示例
class UserController(Controller):
list_users = Route('/users')
def list_users(self, request):
return {'users': ['Alice', 'Bob']}
get_user = Route('/users/{id}')
def get_user(self, request, id):
return {'id': id, 'name': 'Alice'}
app = App()
UserController.register(app)
优势:
- 声明式——关注"是什么"而非"怎么做"
- 描述符负责属性行为(动态绑定handler)
- 元类在类创建阶段收集元数据(路由表、文档)
- 用户代码简洁直观,框架逻辑集中封装