是否可以在Python中创建一个带状态的嵌套函数?

时间:2014-07-03 17:18:55

标签: python

如果自上次报告以来已超过一秒钟,我试图进行更新回调。它看起来像这样

def main_func()
    ...
    start_time = time.time()
    def callback():
        current_time = time.time()
        if current_time - start_time > 1.0:
            print 'working'
            start_time = time.time()
    work_function(args, callback)

由于start_time是本地的,global关键字无法在callback内工作。是否有可以处理向本地函数添加状态的Python范例?

3 个答案:

答案 0 :(得分:3)

正如已经建议的那样,你最好使用一个类,并将状态保存为成员。

同样如已经建议的那样,您可以使用全局变量或nonlocal语句。

第三种(更原始的)替代方法是将状态设置为函数对象的属性

def main_func()
    ...
    def callback():
        current_time = time.time()
        if current_time - callback.start_time > 1.0:
            print 'working'
            callback.start_time = time.time()
    callback.start_time = time.time()
    work_function(args, callback)

答案 1 :(得分:0)

你可以使这项工作,但细节将取决于你正在使用的Python版本。

在Python 3中,您可以使用nonlocal语句来允许callback函数为外部函数范围内的start_time变量赋值。

def main_func()
    ...
    start_time = time.time()
    def callback():
        nonlocal start_time            # new line here
        current_time = time.time()
        if current_time - start_time > 1.0:
            print 'working'
            start_time = time.time()   # this assignment now works as intended
    work_function(args, callback)

在Python 2中,nonlocal不可用,但您可以将值包装在可变容器中(如list)并修改该值而不重新分配变量:

def main_func()
    ...
    start_time = [time.time()]             # wrap time value in a list
    def callback():
        current_time = time.time()
        if current_time - start_time > 1.0:
            print 'working'
            start_time[0] = time.time()    # modify the list in place
    work_function(args, callback)

答案 2 :(得分:0)

有点,但这很糟糕。

    def foo(a):
        def inner(b):
            if b > c[0]:
                c[0] > b
            else:
                print "too low"
        c = [a]
        return inner

>>> bar = foo(5)
>>> bar(5)
too low
>>> bar(6) # silence on success
>>> bar(5)
too low

正如其他人所指出的那样,最好只使用一个对象(你可以用这个解决方案 - 毕竟列表是对象)