有关 Python 修饰函数的问题

2018-07-02 18:37:25 +08:00
 su27k2003

最近在研究 python 修饰函数,虚心请教如下问题。废话不说,先上代码:

import time
from datetime import datetime
from datetime import timedelta

def time_func(time_interval, default=None):
    def decorator(func):
        func.__last_run = datetime.min
        def guard(*args, **kwargs):
            now = datetime.now()
            if now - func.__last_run >= time_interval:
                func.__last_run = now
                return func(*args, **kwargs)
            elif default is not None:
                return default(*args, **kwargs)
        return guard
    return decorator


if __name__ == "__main__":
    
    @time_func(timedelta(seconds=4),None)
    def add():
        print('test')

    add()
    add()

执行结果: 只显示一个'test'

问题: 这个代码实现了在规定时间内( time_interval )限制了函数 add ()的运行次数,只让它运行一次,其余忽略。 请问此代码中为何在执行第二遍 add()的时候跳过了开头的 func.__last_run = datetime.min 而直接进入 guard 中的代码?该怎样理它的解运作原理? Python 新手,十分感谢!

1599 次点击
所在节点    Python
3 条回复
baichi
2018-07-03 03:20:05 +08:00
baichi
2018-07-03 03:21:14 +08:00
billgreen1
2018-07-03 09:49:25 +08:00
这么说吧,你不要调用 add(), 直接在 ipython 里面输入 add, 你会看到 add 其实不是 add 了,而是
<function __main__.time_func.<locals>.decorator.<locals>.guard(*args, **kwargs)>,
其实是 guard,但是这个 guard 绑定了一个它的外部变量,__last_run

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/467560

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX