python 中的延迟函数
在JavaScript中,我习惯于能够调用稍后执行的函数,就像这样,
function foo() {
alert('bar');
}
setTimeout(foo, 1000);
这不会阻止其他代码的执行。
我不知道如何在Python中实现类似的东西。我可以使用 sleep
import time
def foo():
print('bar')
time.sleep(1)
foo()
,但这会阻止其他代码的执行。 (实际上,在我的例子中,阻塞 Python 本身并不是问题,但我无法对该方法进行单元测试。)
我知道线程是为不同步执行而设计的,但我想知道是否有更简单的、类似的东西setTimeout
或 setInterval
存在。
In JavaScript I am used to being able to call functions to be executed at a later time, like this
function foo() {
alert('bar');
}
setTimeout(foo, 1000);
This does not block the execution of other code.
I do not know how to achieve something similar in Python. I can use sleep
import time
def foo():
print('bar')
time.sleep(1)
foo()
but this will block the execution of other code. (Actually in my case blocking Python would not be a problem in itself, but I would not be able to unit test the method.)
I know threads are designed for out-of-sync execution, but I was wondering whether something easier, similar to setTimeout
or setInterval
exists.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
要在延迟后执行函数或使用事件循环(无线程)在给定秒数内重复函数,您可以:
Tkinter
输出
Gtk
输出
Twisted
输出
Asyncio
Python 3.4 引入了新的 用于异步 IO 的临时 API --
asyncio
module:输出
注意:这些方法之间的界面和行为略有不同。
To execute a function after a delay or to repeat a function in given number of seconds using an event-loop (no threads), you could:
Tkinter
Output
Gtk
Output
Twisted
Output
Asyncio
Python 3.4 introduces new provisional API for asynchronous IO --
asyncio
module:Output
Note: there is a slight difference in the interface and behavior between these approaches.
您需要一个
Timer
对象线程
模块。如果您想重复,这里有一个简单的解决方案:不使用
Timer
,只需使用Thread
但向其传递一个工作原理如下的函数:这不会无限执行循环,因为如果处理不当,可能会导致线程无法终止以及其他令人不快的行为。更复杂的方法可能使用基于事件的方法,就像这样。
You want a
Timer
object from thethreading
module.If you want to repeat, here's a simple solution: instead of using
Timer
, just useThread
but pass it a function that works somewhat like this:This won't do infinite loops because that could result in a thread that won't die and other unpleasant behavior if not done right. A more sophisticated approach might use an
Event
-based approach, like this one.像 Javascript 的
setTimeout
这样的异步回调需要事件驱动的架构。Python 的异步框架(例如流行的 twisted)具有
CallLater
可以满足您的要求,但这意味着采用事件驱动您的应用程序中的架构。另一种选择是使用线程并在线程中休眠。 Python 提供了一个计时器来让等待部分很容易。然而,当你的线程唤醒并且你的函数执行时,它位于一个单独的线程中,并且必须以线程安全的方式执行它所做的任何事情。
Asynchronous callbacks like Javascript's
setTimeout
require an event-driven architecture.Asynchronous frameworks for Python like the popular twisted have
CallLater
which does what you want, but it means adopting the event-driven architecture in your application.Another alternative is to use threads and to sleep in a thread. Python providers a timer to make the waiting part easy. However, when your thread awakes and your function executes, it is in a separate thread and must do whatever it does in a thread-safe manner.
抱歉,我无法发布超过 2 个链接,因此有关更多信息,请查看 PEP 380 以及最重要的 asyncio。
除非您坚持使用线程或多处理,否则 asyncio 是此类问题的首选解决方案。它由 GvR 以“Tulip”的名称设计和实现。 GvR 在 PyCon 2013 上推出了这一活动,旨在成为唯一一项活动-loop 来规则(和标准化)所有事件循环(如twisted、gevent 等中的事件循环)并使它们彼此兼容。之前已经提到过 asyncio,但 asyncio 的真正威力是通过 yield from 来释放的。
===============
Sorry, I can't post more than 2 links, so for more information please check PEP 380 and most importantly the documentation of asyncio.
asyncio is the preferred solution to this kind of question unless you insist on threading or multiprocessing. It is designed and implemented by GvR under the name "Tulip". It has been introduced by GvR on PyCon 2013 with the intention to be the one event-loop to rule (and standardize) all event-loops (like the ones in twisted, gevent, etc.) and make them compatible with each other. asyncio has been mentioned before, but the true power of asyncio is unleashed with yield from.
================
JavaScript 可以做到这一点,因为它在事件循环中运行事物。这可以在 Python 中通过使用 Twisted 等事件循环或通过 GLib 或 Qt 等工具包来完成。
JavaScript can do this because it runs things in an event loop. This can be done in Python through use of an event loop such as Twisted, or via a toolkit such as GLib or Qt.
问题是你的普通 python 脚本不能在框架中运行。该脚本被调用并控制主循环。使用 JavaScript,页面上运行的所有脚本都在框架中运行,并且框架在超时后调用您的方法。
我自己没有使用过 pyQt(仅使用过 C++ Qt),但是您可以使用 startTimer() 在任何 QObject 上设置计时器。当计时器到期时,将调用您的方法的回调。您还可以使用 QTimer 并将超时信号连接到任意插槽。这是可能的,因为 Qt 运行一个事件循环,可以在稍后阶段调用您的方法。
The problem is that your normal python script doesn't run in a framework. The script gets called and is in control of the main loop. With JavaScript, all the scripts that runs on your page runs in a framework and it is the framework that invokes your method when the timeout elapses.
I haven't used pyQt myself (only C++ Qt), but you can set a timer on any QObject using startTimer(). When the timer elapse, a callback on your method is invoked. You can also use QTimer and connect the timeout signal to an arbitrary slot. This is possible because Qt runs an event loop that can call your method at a later stage.