框架的声明式脚手架
declare的Python项目详细描述
框架的声明式脚手架
安装
pip install declare
开始
让我们为布雷艇区块建立一个快速模型:
from declare import Model, Field, TypeDefinition import json # Wire format is json: # { # "type": int <- maps to enum # "position": str <- packed x:y:z # } class BlockType(TypeDefinition): types = { 0: "Grass", 1: "Stone", 2: "Diamond" } def load(self, value, context): return BlockType.types[value] def dump(self, value, context): # TODO: index types by value for O(1) lookup for tid, name in BlockType.types.items(): if value == name: return tid class Position(TypeDefinition): ''' [x, y, z] <--> "x:y:z" ''' def load(self, value, context): return [int(v) for v in value.split(':')] def dump(self, value, context): return ':'.join(str(v) for v in value) class Block(Model): type = Field(BlockType) position = Field(Position) @classmethod def load(cls, wire): fields = cls.Meta.fields_by_model_name engine = cls.Meta.type_engine wire = json.loads(wire) kwargs = {} for name, field in fields.items(): kwargs[name] = engine.load(field.typedef, wire[name], {}) return cls(**kwargs) @classmethod def dump(cls, obj): fields = cls.Meta.fields_by_model_name engine = cls.Meta.type_engine kwargs = {} for name, field in fields.items(): kwargs[name] = engine.dump( field.typedef, getattr(obj, name), {}) return json.dumps(kwargs)
让我们设置请求处理程序以使用这些块:
from bottle import route, request @route('/diamond_check') def func(): wire = request.json block = Block.load(wire) if block.type == "Diamond": return {"diamond": True, "position": block.position} return {"diamond": False}
或者,创建菱形:
@route('/make_diamond') def func(): wire = request.json position = Position.load(wire) block = Block(type="Diamond", position=position) return Block.dump(block)
嵌套模型
模型也是类型定义的实例。这意味着模型可以被使用 作为字段,使递归加载/转储变得简单:
class List(TypeDefinition): ''' Adapter for lists of objects ''' def load(self, value, context): return [self.typedef.load(v, context) for v in value] def dump(self, value, context): return [self.typedef.dump(v, context) for v in value] class Region(Model): blocks = Field(List(Block)) @classmethod def load(cls, wire): fields = cls.Meta.fields_by_model_name engine = cls.Meta.type_engine wire = json.loads(wire) kwargs = {} for name, field in fields.items(): kwargs[name] = engine.load(field.typedef, wire[name], {}) return cls(**kwargs) @classmethod def dump(cls, obj): fields = cls.Meta.fields_by_model_name engine = cls.Meta.type_engine kwargs = {} for name, field in fields.items(): kwargs[name] = engine.dump( field.typedef, getattr(obj, name), {}) return json.dumps(kwargs)
实际上,来自Block的相同加载/转储代码在这里是可用的,因为我们 只是从json加载/转储。当类型引擎查找 对于List(Block)类型的加载/转储函数,它将迭代加载/转储 使用block.load和block.dump方法的每个块。