【python】学习笔记17

论坛 期权论坛 期权     
白白成长记   2019-7-8 05:51   3172   0
[h1]python学习笔记(17)[/h1][h3]python强大的修饰器[/h3]
  • 修饰器的基本概念
    1. [/code]def func(message):    print('Got a message: {}'.format(message))    send_message = func    send_message('hello world')
    2. [code]
    复制代码
    def get_message(message):    return 'Got a message: ' + messagedef root_call(func, message):    print(func(message))    root_call(get_message, 'hello world')
    1. [/code]def func(message):    def get_message(message):        print('Got a message: {}'.format(message))    return get_message(message)func('hello world')
    2. [code]
    复制代码
    def func_closure():    def get_message(message):        print('Got a message: {}'.format(message))    return get_messagesend_message = func_closure()send_message('hello world')
    1. [/code]def my_decorator(func):    def wrapper():        print('wrapper of decorator')        func()    return wrapperdef greet():    print('hello world')greet = my_decorator(greet)greet()
    2. [code]
    复制代码
    def my_decorator(func):def wrapper():    print('wrapper of decorator')    func()return wrapper@my_decoratordef greet():    print('hello world')greet()
    1. [/code]def my_decorator(func):def wrapper(*args, **kwargs):    print('wrapper of decorator')    func(*args, **kwargs)return wrapper
    2. [code]
    复制代码
    import functoolsdef my_decorator(func):    @functools.wraps(func)    def wrapper(*args, **kwargs):        print('wrapper of decorator')        func(*args, **kwargs)    return wrapper    @my_decoratordef greet(message):    print(message)greet.__name__
    1. [/code]class Count:def __init__(self, func):    self.func = func    self.num_calls = 0def __call__(self, *args, **kwargs):    self.num_calls += 1    print('num of calls is: {}'.format(self.num_calls))    return self.func(*args, **kwargs)@Countdef example():    print("hello world")example()# 输出num of calls is: 1hello worldexample()# 输出num of calls is: 2hello world
    2. 以上代码可以看到装饰器的强大,虽然用函数也能实现装饰器的作用,但是如果用装饰器的话,就会让代码看起来清晰许多,很多时候需要用到装饰器的技巧。
    3. [list][*]类装饰器
    4. [*]带参数的装饰器
    5. [*]在上面的描述中,我们可以用更简单的写法来标识,用@关键字来作为修饰器的关键字,@后面接着函数名.
    6. [/list][list][*]装饰器的基本定义如下,函数也作为对象返回,同时执行函数,我们把装饰器看做以下即可对装饰器有更加深刻的认识,greet函数指向wrapper函数,且调用了函数自身,类似于函数指针:
    7. [*]闭包,函数对象作为返回值
    8. [/list][list][*]在函数内部定义函数嵌套,调用函数
    9. [*]将函数作为参数,在函数中调用,基本调用示例如下:
    10. [/list][list][*]函数的基本概念,常见的函数调用如下所示,我们可以将函数赋给某个变量,由某个变量进行调用:
    11. [/list][*]python的装饰器的作用
    12. [code]
    复制代码
    import functoolsdef authenticate(func):    @functools.wraps(func)    def wrapper(*args, **kwargs):        request = args[0]        if check_user_logged_in(request): # 如果用户处于登录状态            return func(*args, **kwargs) # 执行函数 post_comment()        else:            raise Exception('Authentication failed')    return wrapper    @authenticatedef post_comment(request, ...)    ...
    在上述代码中对请求request尽心验证,验证时需对身份进行校验,通过统一的装饰器验证函数,提供给其他登录或者通信模块应用。
    1. [/code]import timeimport functoolsdef log_execution_time(func):    @functools.wraps(func)    def wrapper(*args, **kwargs):        start = time.perf_counter()        res = func(*args, **kwargs)        end = time.perf_counter()        print('{} took {} ms'.format(func.__name__, (end - start) * 1000))        return res    return wrapper    @log_execution_timedef calculate_similarity(items):
    2. 其中我们可以到通过装饰器log_execution_time来记录每个函数的运行时间.
    3. [code]
    复制代码
    import functoolsdef validation_check(input):    @functools.wraps(func)    def wrapper(*args, **kwargs):        ... # 检查输入是否合法    @validation_checkdef neural_network_training(param1, param2, ...):    ...
    • 输入合理性检查 我们在实际的程序运行过程中都会对每个参数进行校验,检查参数的合理性和合法性。
    • 日志记录 我们在实际的系统运行时可能需要记录必须的函数调用记录,
    • 身份认证。比如在做客户端或者服务器端进行身份认证时,需要对当前的用户传递过来的消息进行身份认证,那么每次只需要对消息中特定的信息进行验证即可得到结果。比如以下代码:
  • 思考题
    所谓的装饰器,其实就是通过装饰器函数,来修改函数本身的一些功能,使得函数更具有扩展型,而原函数不需要进行修改即可。可以随意扩展函数的功能。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:5
帖子:2
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP