当前位置: 首页 > 面试题库 >

等效于python中的setInterval

苍温文
2023-03-14
问题内容

我最近发布了一个问题,如何在Python推迟函数的执行(样相当于为Javascript
setTimeout),它原来是用一个简单的任务threading.Timer(当然,简单的只要功能不共享状态与其它代码,但这会在任何事件驱动的环境中造成问题。

现在,我试图做得更好并效仿setInterval。对于不熟悉Javascript的用户,setInterval允许每x秒重复调用一次函数,而不会阻止其他代码的执行。我创建了这个示例装饰器:

import time, threading

def setInterval(interval, times = -1):
    # This will be the actual decorator,
    # with fixed interval and times parameter
    def outer_wrap(function):
        # This will be the function to be
        # called
        def wrap(*args, **kwargs):
            # This is another function to be executed
            # in a different thread to simulate setInterval
            def inner_wrap():
                i = 0
                while i != times:
                    time.sleep(interval)
                    function(*args, **kwargs)
                    i += 1
            threading.Timer(0, inner_wrap).start()
        return wrap
    return outer_wrap

用途如下

@setInterval(1, 3)
def foo(a):
    print(a)

foo('bar')
# Will print 'bar' 3 times with 1 second delays

在我看来,它工作正常。我的问题是

  • 似乎过于复杂,我担心我可能错过了一种更简单/更好的机制
  • 装饰器可以在没有第二个参数的情况下被调用,在这种情况下它将永远持续下去。当我说到超越时,我的意思是 永远 -即使sys.exit()从主线程进行调用也不会停止它,也不会命中Ctrl+c。阻止它的唯一方法是从外部杀死python进程。我希望能够从主线程发送停止回调的信号。但是我是线程的初学者-如何在线程之间进行通信?

编辑 如果有人怀疑,这是装饰器的最终版本,这要感谢jd的帮助

import threading

def setInterval(interval, times = -1):
    # This will be the actual decorator,
    # with fixed interval and times parameter
    def outer_wrap(function):
        # This will be the function to be
        # called
        def wrap(*args, **kwargs):
            stop = threading.Event()

            # This is another function to be executed
            # in a different thread to simulate setInterval
            def inner_wrap():
                i = 0
                while i != times and not stop.isSet():
                    stop.wait(interval)
                    function(*args, **kwargs)
                    i += 1

            t = threading.Timer(0, inner_wrap)
            t.daemon = True
            t.start()
            return stop
        return wrap
    return outer_wrap

可以与上述固定次数的重复使用

@setInterval(1, 3)
def foo(a):
    print(a)

foo('bar')
# Will print 'bar' 3 times with 1 second delays

或者可以一直运行直到收到停止信号

import time

@setInterval(1)
def foo(a):
    print(a)

stopper = foo('bar')

time.sleep(5)
stopper.set()
# It will stop here, after printing 'bar' 5 times.

问题答案:

您的解决方案对我来说很好。

有几种与线程通信的方法。要下令停止线程,可以使用threading.Event(),它具有一个wait()可以代替的方法time.sleep()

stop_event = threading.Event()
...
stop_event.wait(1.)
if stop_event.isSet():
    return
...

为使线程在程序终止时退出daemon,请True在调用之前将其属性设置为start()。这也适用于Timer()对象,因为它们是子类threading.Thread。请参阅http://docs.python.org/library/threading.html#threading.Thread.daemon



 类似资料:
  • 问题内容: 当我从解释器编写Python代码时,我可以键入要在当前作用域中定义的名称列表。当我使用交互式控制台(如Firebug,Chrome控制台等)从浏览器开发Javascript代码时,如何以编程方式实现具有相同的信息? 问题答案: 在ChatZilla的代码中,有几个功能可以执行此操作,您必须正确检查许可证以查看是否可以将其撕下来并在任何地方使用。 相关功能可以在 http://hg.mo

  • 问题内容: 在Java中,可以使用 构建器模式 来提供一种更具可读性的方法来实例化具有许多参数的类。在构建器模式中,一个人使用一种方法来构造配置对象以设置命名属性,然后使用它来构造另一个对象。 Python中的等效项是什么?模仿相同实现的最佳方法是吗? 问题答案: 设计模式通常可以用内置语言功能代替。 您的用例 您说:“我想有一个更具可读性的“方法”来实例化具有许多参数的类。” 在Java的情况下

  • 问题内容: 最近,我遇到了一些Java代码,这些代码简单地将一些字符串放入Java TreeSet中,为其实现了基于距离的比较器,然后在日落时分快乐地计算出给定的分数来解决给定的问题。 我的问题 是否有适用于Python的等效数据结构? Java树集看起来基本上是一个有序字典,可以使用某种比较器来实现这种排序。 我看到有一个用于 OrderedDict的Py3K的PEP,但是我使用的是2.6.x。

  • 问题内容: 我正在玩Go,但是我很难做其他语言中非常简单的事情。 我想重现类似的语法: 在Go中,有什么优雅的方法?我真的很想简化我的代码,尤其是在数组上使用函数时。例如: 非常感谢 问题答案: 有趣的是,Rob Pike 刚刚提出了(18小时前)库过滤器,该过滤器可以满足您的要求: 例如查看Choose() 在这里测试: 正如评论中[]指出的那样,该库的GoDoc指出: 软件包包含实用程序功能,

  • 问题内容: 我正在尝试将一些JavaScript代码从MicrosoftAjax移到JQuery。我在MicrosoftAjax中使用了流行的.net方法中的JavaScript等效项,例如String.format(),String.startsWith()等。jQuery中是否具有等效项? 问题答案: ASP.NET AJAX的源代码可供您参考,因此您可以仔细阅读它,并将要继续使用的部分包含在

  • 问题内容: 是否有类似Android上的内容。我知道如何创建自己的线程,但是有没有像摆动计时器那样的东西? 问题答案: 还有Java的TimerTask。这是我的代码中播放音频样本的示例:

  • 问题内容: 我想知道是否有一种方法可以仅使用html在另一个html内包含一些html内容? 替代PHP 这可能吗? 编辑: 这引起了一些混乱,我需要的是“几乎是html标签”,该标签具有在另一个文档中包含html文档的功能。 问题答案: 它不能完全通过HTML来完成。(不过,有iframe,但在这种情况下我认为不符合要求。) 可以使用JavaScript来完成。您可以通过Ajax获得另一个文件,

  • 问题内容: 我正在从xml配置转移到注释。我想转换一个会话范围的bean是 可以通过注释完成此操作吗?如果没有,我该怎么做才能使该声明继续工作? 问题答案: 在spring上下文xml中,执行以下操作: 请注意,尽管如此,你将需要为该包中的所有类编写接口。