Python

python装饰器decorator学习——完成映射

2019-04-22  本文已影响68人  做劲霸男人_31bb
decorator.jpg

python的高级技巧中,一定有装饰器的一席之地。目前掌握的知识还不是很多,我尽量用自己能理解的语言描述清楚。

什么是装饰器?

先贴上官方解释 decorator官方解释 ,看不懂英文的可以将网页翻译成中文再看,凡是都需要耐心。。。

个人愚见:

在遵循 开发封闭 原则的基础上,对原有模块功能进行扩展所用的代码块,就可以解释为装饰器。当然,这只是从功能上解释了下,定义还是看 decorator官方解释 吧。

代码样例

假如要写一个关于url请求方法的模块,为后期减少使用者的配置,定义如下:

{201: put,202: get,203: head,204: delete},调用时传入相应字符即可调用对应请求方法。目前我能想到的有下面4中方法(好像高中解数学题目_)。

以下所有方法忽略异常情况,仅讨论实现方式的区别。

方法一:使用字典完成映射 UrlDict.py

def put():
    print('put')


def get():
    print('get')


def delete():
    print('delete')


def head():
    print('head')


def get_method(method):
    run_method = METHOD_DICT[method]
    return run_method


def run(run_num):
    run_method = get_method(run_num)
    run_method()


METHOD_DICT = {
    '201': put,
    '202': get,
    '203': head,
    '204': delete,
}

if __name__ == '__main__':
    run('202')
    run('201')
    run('203')
    run('204')

优点:简洁明了,实现全部需求。
缺点:每增加一个请求方法,就要在method_dict中添加一对值。如果方法过多,method会过于庞大,且不利于 开发封闭 原则。

方法二:使用globals局变量完成 UrlGlobals.py

def put():
    print('put')


def get():
    print('get')


def delete():
    print('delete')


def head():
    print('head')


def get_method(method):
    run_method = globals()[method]
    return run_method


def run(run_num):
    run_method = get_method(run_num)
    run_method()


if __name__ == '__main__':
    run('put')
    run('head')
    run('get')
    run('delete')

优点:简洁明了,遵循 开发封闭 原则。
缺点:未实现以数字(字符)代替请求的需求,调用配置需使用准确的方法。实质是第一种方法中的METHOD_DICT由globals()替换。

方法三:使用getattr完成 UrlGetattr.py

class RequestUrl(object):

    @staticmethod
    def put():
        print('put')

    @staticmethod
    def get():
        print('get')

    @staticmethod
    def delete():
        print('delete')

    @staticmethod
    def head():
        print('head')

    def get_method(self, method):
        run_method = getattr(self, method)
        return run_method

    def run(self, method):
        run_method = self.get_method(method)
        run_method()


if __name__ == '__main__':
    req = RequestUrl()
    req.run('put')
    req.run('head')
    req.run('get')
    req.run('delete')

优点:简洁明了,遵循 开发封闭 原则。
缺点:未实现以数字(字符)代替请求的需求,调用配置需使用准确的方法。

方法四:使用装饰器完成 UrlDecorator.py

METHOD_DICT = {}


def set_route(run_num):
    def set_func(func):
        METHOD_DICT[run_num] = func

        def call_func(*args, **kwargs):
            return func(*args, **kwargs)

        return call_func

    return set_func


@set_route('201')
def put():
    print('put')


@set_route('202')
def get():
    print('get')


@set_route('204')
def delete():
    print('delete')


@set_route('203')
def head():
    print('head')


def get_method(method):
    run_method = METHOD_DICT[method]
    return run_method


def run(run_num):
    run_method = get_method(run_num)
    run_method()


if __name__ == '__main__':
    run('202')
    run('201')
    run('203')
    run('204')

优点:完成所有需求,遵循 开放封闭 原则。
缺点:使用装饰器理解难度高。

总结

在实际开发过程中,开放封闭 原则是很重要的,因为代码一旦上库运行,后续修改是很困难的,很难清楚的知道有多少处调用。后面3种虽然都遵循了这一原则,只有使用装饰器的方式满足了全部需求。

所以从满足需求来看,只有第一种和最后一种满足了需求,而第一种随着功能的增加,要逐渐修改字典变量METHOD_DICT的长度,虽然修改这个本身并不复杂,但有高大上的解决方式,又有什么理由不去学习呢?

上一篇下一篇

猜你喜欢

热点阅读