Python生成自定义类并添加自定义方法

  最近准备做个简单的web服务器,通过配置url method header 等属性实现自定义的API,框架考虑的是Tornado和PyRestful。然后就遇到了问题,API的数量是动态生成的,每个API的请求方式也不一样。如果单纯的PyRestful是满足不了的。

import pyrestful.rest
import tornado.ioloop
from pyrestful import mediatypes
from pyrestful.rest import get, post

class Book(object):
    isbn = int
    title = str

class BookResource(pyrestful.rest.RestHandler):
    @get(_path="/books/json/{isbn}", _types=[int], _produces=mediatypes.APPLICATION_JSON)
    def getBookJSON(self, isbn):
        book = Book()
        book.isbn = isbn
        book.title = "My book for isbn " + str(isbn)

        return book
  

  因此需要动态生成class及claas的method,还好Python是有对应的语法的:Metaclass

  通过继承type,重写__new__(cls, name, bases, attrs)方法

 class RestHandleMetaclass(type):    

    def __new__(cls, name, bases, attrs):
	    # do something ,such as redefinition attrs 
	    # ps: attr is a tuple
        return type.__new__(cls, name, (RestHandler,), attrs)

 

  接着遇到了第二个问题,@get(_path="/books/json/{isbn}", _types=[int], _produces=mediatypes.APPLICATION_JSON) 如何添加到方法上面。一开始我以为@符号是注解,走了不少弯路,后来才知道@在Python中是用来处理Decorator(装饰器)的。(参考资料:AB)。 由于attrs中的元素是方法,如何生成方法,同时已经被装饰器处理过,同时能修改@get()中的参数,并最终返回一个方法 成了第三个问题。还好pyrestful.rest.get启发了我

def get(*params, **kwparams):
	""" Decorator for config a python function like a Rest GET verb	"""
	def method(f):
		return config(f,'GET',**kwparams)
	return method

  Python中的Method内部是可以定义Method,并返回Method的。同时尝试后发现内部定义的Method是可以加上@get,最终返回装饰器进行处理后的Method

class RestHandleMetaclass(type):
    @staticmethod
    def dynamicDecorator(data):
        _path = "/books/json/" + str(data) + "/{isbn}"
        _types = [int]
        _produces = mediatypes.APPLICATION_JSON

        @get(_path=_path, _types=_types, _produces=_produces)
        def getBookJSON(self, isbn):
            book = Book()
            book.isbn = isbn
            book.title = "My book for isbn " + str(isbn)
            return book

        return getBookJSON

    def __new__(cls, name, bases, attrs):
        for x in range(5):
            attrs["getBookIsbn_" + str(x)] = RestHandleMetaclass.dynamicDecorator(x)
        return type.__new__(cls, name, (RestHandler,), attrs)

  最后补上相关的代码。

class TestA(object, metaclass=RestHandleMetaclass):
    pass

if __name__ == '__main__':
    try:
        print("Start the service")
        app = pyrestful.rest.RestService([TestA])
        app.listen(8080)
        tornado.ioloop.IOLoop.instance().start()
    except KeyboardInterrupt:
        print("\nStop the service")


    

  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值